.PAPER SIZE 60,72 .LEFT MARGIN 9 .TITLE A Practical Introduction to RMS .CENTER;A PRACTICAL INTRODUCTION TO RMS .BLANK 2 .CENTER;RX026 .BLANK 2 .CENTER;Thomas R. Wyant, III .CENTER;E. I. DuPont de Nemours .CENTER;Richmond, Virginia .BLANK 5 .LEFT MARGIN +10;.RIGHT MARGIN -10 .CENTER;Abstract .BLANK The purpose of this paper is to provide an elementary and practical overview of RMS in the context of RSX. Emphasis will be placed on how RMS fits in with the other components (especially FCS), and the complete or partial migration of an FCS-based application to RMS will be discussed. Along the way, an attempt will be made to dispel several myths about RMS. .RIGHT MARGIN +10;.LEFT MARGIN -10 .AUTOPARAGRAPH .HEADER LEVEL 1 Technical overview of RMS First, this paper will attempt to describe what RMS is and is not, and locate it in the context of the RSX Input/Output mechanism. .HEADER LEVEL 2 What RMS Is RMS stands for "Record Management Services". It is a set of subroutines designed to support sequential, relative, and indexed file access. Under RSX, there is a separate set of subroutines misleadingly called FCS (for "File Control Services") that supports access to sequential files only. .HEADER LEVEL 2 What RMS Is Not RMS is not a file organization; there is no such thing as an "RMS" file, either as distinguished from an "FCS" file or in any other sense. It is true that RMS is the only access method that supports relative and indexed files, but that does not make these RMS files. And yes, RMS will read and write sequential files that can also be read and written by FCS, and vice versa. It is in general impossible to tell whether a given sequential file was written by FCS or RMS. .HEADER LEVEL 2 Where RMS Fits In The task of RMS is to locate, read, and write records in any supported file organization. Technically, this involves translating record I/O requests generated by the calling program (or the caller's language OTS) into virtual block QIO requests to the disk's ACP. Thus, RMS represents the lowest level of file I/O that actually resides in the calling program's address space. Because RMS (and FCS) are linked into the program's address space, it is not possible (and should not be necessary) to link the same task against both FCS and RMS. .HEADER LEVEL 1 Application migration Next, we will discuss some of the ins and outs of migrating an existing FCS-based application to RMS. .HEADER LEVEL 2 Why You Might Want To RMS offers the application programmer a number of features that can speed both the program development cycle and the application itself. The author found the following points of interest when considering the migration of an FCS-based application to RMS. .HEADER LEVEL 3 Indexed Files A large variety of applications involve looking up an item in a file, and doing something with the associated record. This kind of thing can be done with sequential files using hashing, index tables, or what have you; but an indexed file is often the best way to implement. .HEADER LEVEL 3 Bucket Locking Unlike FCS, RMS will attempt to manage things when multiple accessors wish to write on the same file. An application that is based on direct-access sequential files might benefit in throughput by migrating to relative files, where locking can take place at the bucket level rather than at the file level. .HEADER LEVEL 3 Transparent DAP Connections RMS will allow a task to transparently access a file on another DECnet node. In this context, "transparent" means that the source code for accessing a remote file is the same as for accessing a local file; the only difference is the presence of a node name in the file name specification. This could be a useful tool for distributing an application. .HEADER LEVEL 2 Possible Complications Like any good thing, RMS has its price. The following drawbacks to the use of RMS as a replacement for FCS were noted. .HEADER LEVEL 3 RMS Requirements And Performance There are occasions where more is less. With their greater functionality, the RMS support routines are significantly larger than their FCS counterparts. Applications with address space problems may find these problems exacerbated by the migration to RMS. The distributed RMS library (RMSRES) can (and should if at all possible) be linked in supervisor mode, to minimize the impact on user mode address space. The way to do this is discussed later on. Where address space is a problem and RMSRES is for some reason not an option, the RMS OTS can be overlaid. Sample overlay descriptor files are provided with RMS and (normally) with high-level languages. Be aware that in the tighter overlays file access and various types of record I/O are on different legs of the overlay; this can result in thrashing, and serious performance degradation. RMS is also slower than FCS when accessing sequential files, all other things being equal. This difference in speed is not great enough to be fatal unless the application is very time critical, but it may be noticable. .HEADER LEVEL 3 FORTRAN Support You will encounter a few instances where the RMS FORTRAN OTS performs differently than the FCS OTS. .HEADER LEVEL 4 DISPOSE='PRINT' Under the RMS OTS this keyword is the equivalent of DISPOSE='SAVE'; that is, it leaves the file on the disk, but does not submit it to the print spooler. The reason is that once FORTRAN has opened a file, it deallocates the File Access Block and associated data structures. This means that the file ID is no longer readily available, and the directory ID even less so; and both are needed for the standard spooler send/receive packet. Various fixes are possible, but all require source modifications and supporting MACRO-11 subroutines, and none are particularly straightforward. The most obvious involves a MACRO-11 routine that: .LIST .LE;Calls $FCHNL to locate the FORTRAN Logical Unit Block (LUB); .LE;Calls FABRQ$ if it is necessary to allocate a FAB (ie - if D.PFAB in the LUB is zero); .LE;Converts the saved file name and type to RAD50, and the saved version to binary (using the FEAT$ executive directive to determine whether octal or decimal is the correct radix); .LE;Calls RQMEM$ to allocate space for one File Name block (NAM) and two file name buffers, and initializes them; .LE;Calls the RMS macros $DISCON and $CLOSE to disconnect the record stream and close the file (the FORTRAN OTS should not be used at this point); .LE;Performs a directory lookup on the fully qualified file name (which involves initializing the FAB and NAM, and executing the RMS $PARSE and $SEARCH macros); .LE;Enters the information thus gained in the spooler packet and sends it to the spooler; .LE;Calls RLMEM$ to deallocate the NAM block and the file name buffers; .LE;Closes the channel again, this time with the FORTRAN CLOS$ routine. .END LIST .HEADER LEVEL 4 SHARED Sequential Files In many ways they aren't. This is in fact documented (and is therefore a feature rather than a bug) in the FORTRAN user's guide. The problem is that FORTRAN requests shared write when you open with the SHARED keyword; however, RMS can't do bucket locking on a sequential file, so it executes the open with shared read access only. The net result is that a READONLY, SHARED open fails unless all other openers also requested READONLY, SHARED. Having more than one writer to a sequential file involves taking your life into your own hands, and RMS simply won't allow it. If your application does this, you're stuck with FCS. However, there is a way to allow one reader and many writers. This involves a USEROPEN routine (in MACRO-11) that tests whether a shared write was requested (ie - whether FB$WRI is set), and if so requests "anything goes" access (ie - sets FB$UPI). The "anything goes" request will override the shared write for a sequential file; otherwise, it will be ignored. .HEADER LEVEL 3 Error Analysis The RMS OTS returns different I/O codes than the FCS OTS does. Any pieces of code that attempts to do error analysis below the level of the FORTRAN (or other high-level language) OTS error code will have to be identified and modified. .HEADER LEVEL 3 Missing Low-level Functionality There are a few pieces of functionality that just don't exist yet in RMS. These are typically things that are normally done only by FCS based utilities (ie - PIP). Many gaps can be filled by issuing ACP QIOs (documented in the back of the Drivers manual). You will have to code the QIOW$ calls yourself, as RMS seems to lack a .XQIO call. .HEADER LEVEL 2 How To Get There In general, the migration of an application to RMS involves converting the source, the taskbuild command files, and (if desired) the files. Some of these steps are trivial; others may be more significant. .HEADER LEVEL 3 FORTRAN Unless you hit one or more of the possible complications listed above, you need do very little to your FORTRAN code. Opening relative and indexed files require modifications to your OPEN statements, as do keyed reads of indexed files. If your module doesn't do one of these things, you don't even need to recompile. .HEADER LEVEL 3 MACRO-11 Your MACRO-11 code, on the other hand, will require a complete rewrite of the file access portions. Fortunately, the RMS Macro Programmer's Guide is reasonably easy to follow (at least compared to the I/O Operations Guide, which documents FCS), and the FORTRAN OTS Guide also covers both FCS and RMS interfaces in detail, for those MACRO-11 modules that have to interface with FORTRAN modules or the FORTRAN OTS. .HEADER LEVEL 3 Linking You will need to link your RMS task to both the language's RMS OTS (if any), and the RMS support routines found in RMSLIB. Address space is best conserved by linking to RMSRES in supervisor mode. In order to do this, you need to link into your task (in the root if it is overlaid), the following modules: .BLANK;.INDENT +4;LB:[1,1]RMSLIB/LB:R0EXSY:R0AUTS:R0IMPA .BLANK Also, you need to specify the following taskbuilder option: .BLANK;.INDENT +4;RESSUP = LB:[3,54]RMSRES/SV:0 .BLANK If you are linking against DAPRES, you must include module .BLANK;.INDENT +4 LB:[1,1]RMSDAP/LB:R0AULS .BLANK instead of R0AUTS, and you must specify .BLANK;.INDENT +4 LIBR = DAPRES:RO .BLANK in addition to RMSRES. If your FORTRAN (or other language) RMS OTS is not in SYSLIB, you will need to refer to it specifically IN EACH SEGMENT OF THE TASK, after all FORTRAN modules have been referred to, but before the references to RMSLIB (noting that there will be no references to RMSLIB if you link to RMSRES). This is especially true if your language's FCS OTS is in SYSLIB; in this case you will be informed of your error not by undefined references in the taskbuilder, but by truly bizarre run time errors as the FCS and RMS routines try vainly to cope with each other's data bases and support routines. .HEADER LEVEL 3 File conversion No conversion of files is required to move an application from FCS to RMS. However, as mentioned above, you may wish to convert your direct access sequential files to relative files. Once the files to be converted have been identified, the following two-step procedure must be executed on each file: .LIST .LE;Run RMSDES to create an empty relative file with the same record size as your sequential data file; .LE;Run RMSCNV to load the data from your sequential file into the relative file. .END LIST .HEADER LEVEL 2 Going Half Way Although a given task must be linked to either FCS or RMS, there is no reason why all tasks in an application package must run the same record access method. If the bulk of an application only needs sequential files, or if portions of the application need functionality that is unsupported (or poorly supported) in RMS, you may wish to migrate only part of an application to RMS. This is perfectly possible, though it raises unique problems that a total migration would not: .HEADER LEVEL 3 Supporting Two Language OTSes This is not the problem it once was, as FORTRAN-77 now supports multiple OTSes. It was never really much of one, as it wasn't hard to run the F77 installation twice. As mentioned above, the biggest problem is probably linking against the RMS OTS when the FCS OTS is lurking in SYSLIB, waiting to be pulled in if you miss a reference to the RMS OTS in the task build command file. .HEADER LEVEL 3 Multiple Versions Of MACRO-11 Support Routines This is something that both the MACRO-11 programmer and the high-level language programmer are just going to have to live with. The MACRO-11 programmer can perhaps make life easier for himself by maintaining one source module for each support routine, conditionalized for FCS or RMS, and assembling twice with appropriate prefix files. A variant on this is having a support routine assemble for FCS by default, and then write a stub RMS module that sets up an RMS assembly and then _.INCLUDEs the main source module. There seems little way of preventing the high-level language programmer from having to know which modules are RMS dependent. If the application is built directly from object files, there's really no way at all. If the application is linked against a library of application support modules, the library can be broken into three: FCS-specific, RMS-specific, and neutral, with the application linked against the neutral library and the FCS (or RMS) specific library, in that order. .HEADER LEVEL 3 Error Analysis The analysis of low-level I/O errors will now have to take into account whether the error code being analyzed was produced by FCS or RMS. .HEADER LEVEL 3 File Sharing between FCS and RMS As mentioned above, the file sharing characteristics of FCS and RMS are different. This can best be presented with a table giving the OTS code returned by the second attempt to open a sequential file after the first has been opened in a given manner: .BLANK;.TEST PAGE 16;.NOFILL | Second open | +-----------------------+---------------------------+ | FCS | RMS | First+-----+-----+-----+-----+------+------+------+------+ open |RO,SH| RO | SH | |RO,SH | RO | SH | | -----+-----+-----+-----+-----+------+------+------+------+ FCS: | | | | | | | | | RO,SH| 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | RO | 1 | 1 | -27 | -27 | 1 | 1 | -704 | -704 | SH | 1 | -29 | 1 | -29 | -704 | -704 | -704 | -704 | | 1 | -29 | -27 | -29 | -704 | -704 | -704 | -704 | RMS: | | | | | | | | | RO,SH| 1 | 1 | -27 | -27 | 1 | 1 | -704 | -704 | RO | 1 | 1 | -27 | -27 | 1 | 1 | -704 | -704 | SH | 1 | -29 | -27 | -29 | -704 | -704 | -704 | -704 | | 1 | -29 | -27 | -29 | -704 | -704 | -704 | -704 | .BLANK;.FILL If you write a USEROPEN subroutine as described above to set FB$UPI when FB$WRI is set, you get the following characteristics: .BLANK;.TEST PAGE 16;.NOFILL | Second open | +-----------------------+---------------------------+ | FCS | RMS | First+-----+-----+-----+-----+------+------+------+------+ open |RO,SH| RO | SH | |RO,SH | RO | SH | | -----+-----+-----+-----+-----+------+------+------+------+ FCS: | | | | | | | | | RO,SH| 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | RO | 1 | 1 | -27 | -27 | 1 | 1 | -704 | -704 | SH | 1 | -29 | 1 | -29 | 1 | -704 | -704 | -704 | | 1 | -29 | -27 | -29 | 1 | -704 | -704 | -704 | RMS: | | | | | | | | | RO,SH| 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | RO | 1 | 1 | -27 | -27 | 1 | 1 | -704 | -704 | SH | 1 | -29 | -27 | -29 | 1 | -704 | -704 | -704 | | 1 | -29 | -27 | -29 | 1 | -704 | -704 | -704 | .BLANK;.FILL .HEADER LEVEL 1 Wrapup Although RMS is a different environment than FCS, the features it provides are a superset of the familiar FCS functionality. The conversion of an existing application to take advantage of these features may be desirable. Alternatively, the bulk of an application may remain FCS based, with enhancements done with RMS. .HEADER LEVEL 1 Bibliography .LIST "o" .LE;PDP-11 Fortran-77 Object Time System Reference Manual .LE;PDP-11 Fortran-77 User's Guide .LE;RSX-11M/M-PLUS RMS-11 MACRO Programmer's Guide .LE;RSX-11M/M-PLUS RMS-11 User's Guide .LE;RSX-11M/M-PLUS RMS-11 Utilities .END LIST