{"id":6,"date":"2013-01-01T01:01:43","date_gmt":"2013-01-01T07:01:43","guid":{"rendered":"http:\/\/tommysprinkle.com\/mvssp\/?p=6"},"modified":"2013-05-22T08:35:00","modified_gmt":"2013-05-22T13:35:00","slug":"srb-service-request-block-overview","status":"publish","type":"post","link":"https:\/\/tommysprinkle.com\/mvssp\/2013\/01\/01\/srb-service-request-block-overview\/","title":{"rendered":"SRB &#8211; Service Request Block Overview"},"content":{"rendered":"<p>A Service Request Block (SRB) defines a dispatchable unit of work (Service Routine) in MVS.\u00a0 A dispatchable unit of work is just a fancy way of saying some code that will be run by the dispatcher.\u00a0 A SRB as opposed to a Task Control Block is considered a lightweight task.\u00a0 This simply means it has less overhead associated with creating and dispatching it.\u00a0 It also means that the capabilities are more limited.\u00a0 SRB routines always run in supervisor mode.\u00a0 They may not issue SVC calls and they are nonpreemptiable &#8211; meaning a higher priority task cannot preempt them.<\/p>\n<p>SRB routines can be scheduled to run in any Address Space.\u00a0 This makes them very useful for cross memory access in a pre-XA environment.\u00a0 This is exactly what we will ultimately do with our SRB routine.\u00a0 We will schedule it into an address space to allow us to copy local memory into a Common Service Area (CSA) storage (shared memory location).<\/p>\n<p>SRB routines are fairly simple but we do have to be careful since we are writing code that executes in supervisor mode and key zero.\u00a0 When I was initially testing my SRB code I did manage to crash my MVS system a few times due to simple coding mistakes. Fortunately, with Hercules I can IPL and be back up and running quickly.\u00a0 It also helps that I am the only user on the system.<\/p>\n<p>A SRB routine is created by allocating some memory to hold the SRB and then using the SCHEDULE macro to schedule it for execution.\u00a0 The SRB must reside in fixed, commonly-addressable storage.<\/p>\n<h2>SRB Control Block<\/h2>\n<p>The SRB is defined by the macro IHASRB in SYS1.MACLIB.<\/p>\n<pre>SRBSECT\u00a0 DSECT\r\nSRB\u00a0\u00a0\u00a0\u00a0\u00a0 DS\u00a0\u00a0\u00a0 0A\r\nSRBID\u00a0\u00a0\u00a0 DS\u00a0\u00a0\u00a0 CL4\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 EBCDIC ACRONYM\u00a0\u00a0 FOR SRB\r\nSRBFLNK\u00a0 DS\u00a0\u00a0\u00a0 A\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 FORWARD CHAIN FIELD\r\nSRBASCB\u00a0 DS\u00a0\u00a0\u00a0 A\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 PTR TO ASCB OF ADDRESS SPACE\r\n*\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 SRB IS TO BE DISPATCHED TO\r\nSRBFLC\u00a0\u00a0 DS\u00a0\u00a0\u00a0 0CL8\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 SRB AREA MOVED TO LOW CORE\r\nSRBCPAFF DS\u00a0\u00a0\u00a0 BL2\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 CPU AFFINITY MASK\r\nSRBPASID DS\u00a0\u00a0\u00a0 H\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 PURGEDQ ASID IDENTIFIER\r\nSRBPTCB\u00a0 DS\u00a0\u00a0\u00a0 A\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 PURGEDQ TCB IDENTIFIER\r\nSRBEP\u00a0\u00a0\u00a0 DS\u00a0\u00a0\u00a0 A\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ENTRY POINT OF ROUTINE\r\nSRBRMTR\u00a0 DS\u00a0\u00a0\u00a0 A\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ADDRESS OF RESOURCE MGR RTN\r\nSRBPARM\u00a0 DS\u00a0\u00a0\u00a0 A\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 USER PARAMETER\r\nSRBSAVE\u00a0 DS\u00a0\u00a0\u00a0 A\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 SAVE AREA POINTER\r\nSRBPKF\u00a0\u00a0 DS\u00a0\u00a0\u00a0 B\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 PROTECT KEY INDICATION\r\nSRBPRIOR DS\u00a0\u00a0\u00a0 B\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 PRIORITY LEVEL INDICATION\r\nSRBPSYS\u00a0 EQU\u00a0\u00a0 0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 SYSTEM PRIORITY LEVEL\r\nSRBPNONQ EQU\u00a0\u00a0 4\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 NON-QUIESCEABLE PRIORITY\r\n         DS\u00a0\u00a0\u00a0 BL2\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 RESERVED\r\n         DS\u00a0\u00a0\u00a0 A\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 RESERVED\r\nSRBEND\u00a0\u00a0 EQU\u00a0\u00a0 *\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 END OF SRB\r\nSRBSIZE\u00a0 EQU\u00a0\u00a0 SRBEND-SRBSECT\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 SIZE OF SRB<\/pre>\n<p>SRBID is the eyeball identifier for the block and should contain &#8216;SRB .<\/p>\n<p>SRBFLNK if the forward chain pointer and should be initialized to binary zeros.<\/p>\n<p>SRBASCB is the address of the ASCB for the address space this SRB is to be dispatched into.<\/p>\n<p>SRBCPAFF is a bitmask that indicates which CPUs may dispatch this SRB.\u00a0 If it is binary zero or all ones the SRB can be dispatched to any CPU.\u00a0 Since MVS 3.8 usually only runs on single CPU systems we can set it to zeros.<\/p>\n<p>SRBPASID may contain a pointer to the ASCB of the address space associated withthis SRB.\u00a0 It may be set to zero if SRBPTCB is also zero otherwise it must be specified.<\/p>\n<p>SRBPTCB may contain a pointer to the TCB associated with this SRB.\u00a0 If it is specified the SRBPASID field must also be set.\u00a0 If these fields are set and a double failure occurs then the associated TCB will be scheduled for abnormal termination (ABEND).\u00a0 A double failure occurs when an error has been trapped by a recovery routine and the recovery routine also fails.\u00a0 Setting this field also allows the SRB to be purged if the associated TCB is terminated.\u00a0 This field may be set to zero if not needed.<\/p>\n<p>SRBEP is the entry point of the SRB routine.<\/p>\n<p>SRBRMTR is the address of a Resource Manager Termination Routine that is called if the SRB is purged before it is scheduled.\u00a0 The RMTR is responsible for any cleanup.<\/p>\n<p>SRBPARM is a fullword parameter value that is passed to the SRB routine when it is dispatched.<\/p>\n<p>SRBSAVE is the address of the status save area and must be initialized to zeros.<\/p>\n<p>SRBPKF specifies the PSW protect key for the SRB routine.\u00a0 The high-order four bits specify the protect key and the low-order four bits must be zero.<\/p>\n<p>SRBPRIOR is the priority of a GLOBAL SRB.\u00a0 GLOBAL SRBs are dispatched at a higher priority than any address space.\u00a0 LOCAL SRBs are dispatched at the priority of the address space they run in but at a higher priority than any TCB.\u00a0 GLOBAL SRBs have an additional priority level that indicates if they are for general system usage or a special priority necessary to quiesce SRBs.\u00a0 A value of zero indicates a general system SRB.\u00a0 A value of four indicates a priority of NONQ (nonquiesceable).\u00a0 We can always set this value to zero.<\/p>\n<p>The additional reserved fields should be set to binary zeros.<\/p>\n<h2>CSA &#8211; Global Storage<\/h2>\n<p>The SRB must be located in Fixed, Global storage.\u00a0 When system storage is allocated by GETMAIN the type of stroage is specified by the subpool.\u00a0 Each system subpool has a set of characteristics associated with it.\u00a0 We will place our SRB in Common Service Area (CSA) stroage.\u00a0 There are several subpools that are associated with CSA, each haveing different characteristics.<\/p>\n<table class=\"aligncenter\" style=\"width: 468px; height: 260px;\" border=\"0\" align=\"center\">\n<tbody>\n<tr style=\"background-color: #fdff83;\">\n<td><strong>Subpool<\/strong><\/td>\n<td><strong>Pageable<\/strong><\/td>\n<td><strong>Protect Key<\/strong><\/td>\n<td><strong>Fetch Protect<\/strong><\/td>\n<\/tr>\n<tr style=\"background-color: #11ee33;\">\n<td>227<\/td>\n<td>Fixed<\/td>\n<td>Requester Key<\/td>\n<td>Yes<\/td>\n<\/tr>\n<tr style=\"background-color: #b5ffbd;\">\n<td>228<\/td>\n<td>Fixed<\/td>\n<td>Requester Key<\/td>\n<td>No<\/td>\n<\/tr>\n<tr style=\"background-color: #11ee33;\">\n<td>231<\/td>\n<td>Pageable<\/td>\n<td>Requester Key<\/td>\n<td>Yes<\/td>\n<\/tr>\n<tr style=\"background-color: #b5ffbd;\">\n<td>239<\/td>\n<td>Fixed<\/td>\n<td>Zero<\/td>\n<td>Yes<\/td>\n<\/tr>\n<tr style=\"background-color: #11ee33;\">\n<td>241<\/td>\n<td>Pageable<\/td>\n<td>User Key<\/td>\n<td>No<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>For our purposes we will use subpool 228 as it meets our requirements of being fixed (nonpageable) CSA.\u00a0 Now is proabably a good time to mention that CSA storage is explicitly freed.\u00a0 Once it is allocated by a GETMAIN request it remains allocated untill a FREEMAIN is issued, or until the next IPL.\u00a0 If we allocate CSA we should always have a plan to free it.<\/p>\n<h2>APF Authorization<\/h2>\n<p>Before we can allocate CSA storage we must be authorized.\u00a0 There are various ways to accomplish this goal.\u00a0 We can run from an authorized library and set the AC flag at linkedit.\u00a0 When the program specified on the EXEC statement in JCL is in an APF authorized library and the AC flag is set in the load module a bit will be set in the JSCB indicating the program is APF authorized.\u00a0 Since I am interested in poking around inside MVS and since I am not too concerned about security on my personal MVS system I have installed a user SVC that will set or clear the APF bit in the JFCB.\u00a0 By calling the SVC to set the bit it appars to MVS that I am running from an APF authorized library.<\/p>\n<p>Once we have the APF bit set we can use the MODESET macro to get into supervisor state and key zero.\u00a0 The MODESET macro has two parameters: MODE= and KEY=.\u00a0 MODE is used to set the PSW to either supervisor state (MODE=SUP) or problem program stat (MODE=PROB).\u00a0 The KEY parameter can be used to set the PSW protection key to zero (KEY=ZERO) or the protect key associated with the TCB (KEY=NZERO).\u00a0 It should be noted that once we are in supervisor mode we can also switch PSW keys using the SPKA privledged instruction.<\/p>\n<h2>A Simple Program To Schedule A SRB<\/h2>\n<p>We now know enough to write a simple program to schedule a SRB.\u00a0 Our initial SRB routine will not do anything except immediately exit but it will allow us to get through the basics of creating, scheduling and running a SRB routine.<\/p>\n<pre>SRB01\u00a0\u00a0\u00a0 CSECT ,\r\n        STM\u00a0\u00a0 R14,R12,12(R13)\r\n        LR\u00a0\u00a0\u00a0 R12,R15\r\n        USING SRB01,R12\r\n*\r\n        LA\u00a0\u00a0\u00a0 R1,SAVEA\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 CHAIN\r\n        ST\u00a0\u00a0\u00a0 R13,4(,R1)\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ON\r\n        ST\u00a0\u00a0\u00a0 R1,8(,R13)\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 SAVE\r\n        LR\u00a0\u00a0\u00a0 R13,R1\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 AREA<\/pre>\n<p>We begin by saving the caller&#8217;s registers, establishing a base register, and setting up a new register save area.<\/p>\n<pre>*                                                     \r\n******************************************************\r\n*                     GET INTO SUP STATE, KEY ZERO    \r\n******************************************************\r\n*                                                     \r\n         LA    R1,=C'AUTH'        &lt;&lt; GET APF AUTH &gt;&gt;  \r\n         SVC   245                &lt;&lt;     AC = 1   &gt;&gt;  \r\n*                                                     \r\n         MODESET MODE=SUP,KEY=ZERO                    \r\n*                                                     \r\n         LA    R1,0               &lt;&lt; RESET APF AUTH &gt;&gt;\r\n         SVC   245                &lt;&lt;      AC = 0    &gt;&gt;<\/pre>\n<p>Next I invoke my user SVC to establish APF authorization. On my system I use SVC 245. If you run from an APF authorized library you can remove the SVC 245 calls. If you have a similar SVC installed on your system you may need to modify the code to work.<\/p>\n<p>Next we issue the MODESET macro to set our PSW to supervisor state and protect key zero. Once we are in supervisor state I usually call my SVC 245 to turn off the APF bit in the JSCB. As long as we are in supervisor state or in PSW protect key of 0 through 7 we are considered APF authorized by MVS.<\/p>\n<pre>*****************************************************\r\n*                       SET UP CSA STORAGE           \r\n*****************************************************\r\n*                                                    \r\n         LA    R4,WKLEN           LENGTH OF WORK AERA\r\n*                                                    \r\n         GETMAIN R,LV=(R4),SP=228                    \r\n*                                                    \r\n         LR    R6,R1                                 \r\n         USING WKAREA,R6          MAP CSA STORAGE    \r\n*                                                    \r\n         XC    WKAREA(WKLEN),WKAREA<\/pre>\n<p>Now that we are in supervisor state and key zero we can allocate our CSA storage. WKLEN is an equated symbol that represents the lenght of our DSECT used to map our CSA storage.\u00a0 We can then issue a GETMAIN request for subpool 228 to get CSA storage that is globally accessable from all address spaces.\u00a0 This storage is fixed, non-pageable and will not be fetch protected.\u00a0 We then save the address of our CSA storage in register 6 and map it with our DSECT.\u00a0 Finally the storage area is cleared to binary zeros using the exclusive or characters instruction.<\/p>\n<pre>WKAREA\u00a0\u00a0 DSECT ,\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\r\nSRBAREA\u00a0 DS\u00a0\u00a0\u00a0 CL(44)\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\r\nSRBCODE\u00a0 DS\u00a0\u00a0\u00a0 CL(ENDSRTN-SRBRTN) \u00a0\r\n*\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\r\n*\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\r\nWKLEN\u00a0\u00a0\u00a0 EQU\u00a0\u00a0 *-WKAREA<\/pre>\n<p>Here is our DSECT for our common storage.\u00a0 First we need 44 bytes to contain the SRB control block.\u00a0 Next we need a place to copy our SRB routine executable code into CSA.\u00a0 Since we ultimately plan to schedule a SRB into another address space the code in our private storage area would be unavailable.<\/p>\n<pre>*\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 L\u00a0\u00a0\u00a0\u00a0 R8,CVTPTR\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 CVT ADDRESS\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 L\u00a0\u00a0\u00a0\u00a0 R8,0(,R8)\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 PSATNEW\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 L\u00a0\u00a0\u00a0\u00a0 R8,12(,R8)\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 CURRENT ASCB (OURS)<\/pre>\n<p>Next we get the address of the ASCB for the address space we are currently located.\u00a0 First we get the address of the CVT which is always located in low memory at location X&#8217;10&#8217; .\u00a0 I often simply would code\u00a0 L\u00a0\u00a0 R8,16\u00a0 but here I use the label generated by the CVT mapping macro.\u00a0 The first word of the CVT points to an area that contains the address of our TCB and our ASCB that is currently dispatched.\u00a0 We get the ASCB address in register 8 and save it for later.<\/p>\n<pre>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 LA\u00a0\u00a0\u00a0 R2,SRBCODE\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 SRB CODE IN CSA\u00a0\u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 LA\u00a0\u00a0\u00a0 R3,ENDSRTN-SRBRTN\u00a0 LENGTH OF SRB ROUTINE\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 LA\u00a0\u00a0\u00a0 R4,SRBRTN\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 MODEL CODE TO COPY\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 LR\u00a0\u00a0\u00a0 R5,R3\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 MVCL\u00a0 R2,R4\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 COPY INTO CSA<\/pre>\n<p>Now we need to copy our SRB routine into CSA.\u00a0 Here it set up the registers and use the MVCL instruction to copy the code.\u00a0 You could also use one or more MVC instructions depending on the length of the code.\u00a0 The advantage of using MVCL is we don&#8217;t have to keep checking the size of the SRB executable routine and add an additional MVC instruction when we exceede a 256 byte boundary.<\/p>\n<pre>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 LA\u00a0\u00a0\u00a0 R7,SRBAREA\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 SRB STORAGE AREA\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 USING SRB,R7\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 XC\u00a0\u00a0\u00a0 0(SRBSIZE,R7),0(R7)\u00a0\u00a0\u00a0 CLEAR<\/pre>\n<p>Next I clear the SRB control block to binary zeros.\u00a0 This is not really necessary since I cleared the entire area after the GETMAIN but I include it here so when we later reuse the SRB control block I am reminded to clear it first.<\/p>\n<pre>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 MVC\u00a0\u00a0 SRBID,=CL4'SRB '\u00a0\u00a0 SRB ID\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\r\n*\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ST\u00a0\u00a0\u00a0 R8,SRBASCB\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 TARGET ASCB TO SCHEDULE TO \u00a0\r\n*\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\r\n*\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 LA\u00a0\u00a0\u00a0 R1,SRBCODE\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 SRB ENTRY POINT \u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ST\u00a0\u00a0\u00a0 R1,SRBEP\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\r\n*\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 LA\u00a0\u00a0\u00a0 R1,SRBCLEAN-SRBRTN(,R1)\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 SRB PURGE ROUTINE\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ST\u00a0\u00a0\u00a0 R1,SRBRMTR\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\r\n*\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 LA\u00a0\u00a0\u00a0 R1,0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 PARM LIST\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ST\u00a0\u00a0\u00a0 R1,SRBPARM<\/pre>\n<p>Now we can fill in the required fileds for the SRB control block.\u00a0 First we move in the eyeball identifier &#8216;SRB &#8216;.\u00a0 For now we will schedule the SRB into our own address space.\u00a0 We set the entry point address to the location in CSA where we copied the SRB routine executable code.\u00a0 We also set the entry point of a purge routnie.\u00a0 Since our SRB routine will immediately exit we don&#8217;t need to pass any parameters for now.\u00a0 This completes our SRB control block and it is now ready for scheduling.<\/p>\n<pre>*************************************************\r\n*\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 SCHEDULE SRB AND WAIT\u00a0\u00a0 \u00a0\r\n*************************************************\r\n*\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 SCHEDULE SRB=(R7),SCOPE=LOCAL<\/pre>\n<p>We can now use the SCHEDULE macro to schedule to add our SRB to the dispatcher queue.\u00a0 To issue the SCHEDULE macro we must be in key zero and supervisor state.\u00a0 We must also include the mapping macros for the CVT and SRB data areas.\u00a0 We must provide the address of our SRB in CSA and we set our priority to LOCAL or address space priority.<\/p>\n<pre>*\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 STIMER WAIT,DINTVL=WAITTIME\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 WAIT FOR SRB TO COMPLETE\r\n*<\/pre>\n<p>Now we can issue a WAIT macro to pause and give the SRB time to execute.\u00a0 Since our SRB does not do anything we don&#8217;t have any indication of when it is complete.\u00a0 By waiting 10 seconds (which is a very long time) our SRB should have plenty of time to be dispatched and to complete execution before we clean up.<\/p>\n<pre>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 DS\u00a0\u00a0\u00a0 0D\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\r\nWAITTIME DC\u00a0\u00a0\u00a0 C'00001000'\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 WAIT 10 SECONDS \r\n*\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 HHMMSSTH<\/pre>\n<p>Our wait time value must be in a double word in unpacked format.<\/p>\n<pre>CLEANUP\u00a0 DS\u00a0\u00a0\u00a0 0H\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 LA\u00a0\u00a0\u00a0 R4,WKLEN\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\r\n*\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 FREEMAIN R,LV=(R4),A=(R6),SP=228 \u00a0\r\n*\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 MODESET MODE=PROB,KEY=NZERO<\/pre>\n<p>When we exit from our wait we can cleanup and exit.\u00a0 First it is important to free the CSA stroage we allocated.\u00a0 If we fail to free the CSA it will remain allocated until the next IPL.\u00a0 Failure to free CSA storage can result if running out of CSA and make an IPL necessary.\u00a0 It is always good practice to make every effort to clean up any system resources we use.\u00a0 For production quality code we would include some error recovery code to free the CSA in the event our program abnormally terminated.\u00a0 Since we are testing in a non-production environment it is not a necessity.<\/p>\n<p>As part of our cleanup we also reset the PSW back to problem program state and TCB storage protect key.<\/p>\n<pre>EXIT\u00a0\u00a0\u00a0\u00a0 DS\u00a0\u00a0\u00a0 0H\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 SLR\u00a0\u00a0 R15,R15\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 SET RETURN CODE \u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 L\u00a0\u00a0\u00a0\u00a0 R13,4(,R13)\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 UNCHAIN SAVE AREA \r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 L\u00a0\u00a0\u00a0\u00a0 R14,12(,R13)\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 RESTORE R14\u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 LM\u00a0\u00a0\u00a0 R0,R12,20(R13)\u00a0\u00a0\u00a0\u00a0 RESTORE REGS 0-12 \r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 BR\u00a0\u00a0\u00a0 R14\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 RETURN TO CALLER<\/pre>\n<p>Now all that is left is to restore the caller&#8217;s registers and exit back to the caller.<\/p>\n<h2>Constants and Data Areas<\/h2>\n<p>We need to define one constant, our wait time.\u00a0 We also need to generate any literal constants using LTORG.\u00a0 We also have one data area, our register save area.<\/p>\n<pre>         DS    0D                                  \r\nWAITTIME DC    C'00001000'        WAIT 10 SECONDS  \r\n*                HHMMSSTH                          \r\n*                                                  \r\n*                                                  \r\n         LTORG ,                                   \r\n*                                                  \r\n*                                                  \r\nSAVEA    DS    18F                SAVE AREA<\/pre>\n<h2>SRB Routine Code<\/h2>\n<p>Now all we need is the code for the SRB routine.\u00a0 For now we can keep it very simple and as soon as our SRB routine is dispatched it will immediately exit.<\/p>\n<pre>SRBRTN   DS    0H                                     \r\n         LR    R6,R15             SRB ROUTINE EP      \r\n         USING SRBRTN,R6                              \r\n*                                                     \r\n         LR    R4,R1              SAVE PARM REGISTER  \r\n*                                                     \r\n         LR    R5,R14             SAVE RETURN ADDRESS \r\n*                                                     \r\n         BR    R5                  DONE - EXIT        \r\n*                                                     \r\n*                                                     \r\nSRBCLEAN DS    0H                  SRB PURGE ROUTINE                      \r\n         BR    R14\r\n*                     \r\n*                     \r\n         LTORG ,      \r\n*                     \r\n*                     \r\n         DROP  R6     \r\n*                     \r\n*                     \r\nENDSRTN  EQU   *<\/pre>\n<h2>CSA Storage Area Dsect<\/h2>\n<p>Now we need our DSECT that maps our CSA storage.<\/p>\n<pre>WKAREA   DSECT ,                   \r\nSRBAREA  DS    CL(44)              \r\nSRBCODE  DS    CL(ENDSRTN-SRBRTN)  \r\n*                                  \r\n*                                  \r\nWKLEN    EQU   *-WKAREA<\/pre>\n<h2>Finishing Touches<\/h2>\n<p>All that is missing to complete our program is a few system data area mapping macros and the register equates.<\/p>\n<pre>*                        \r\n         PRINT OFF       \r\n         CVT   DSECT=YES \r\n         IHASRB  ,       \r\n         IHAPSA  ,       \r\n*                        \r\n*                        \r\nR0       EQU     0 \r\nR1       EQU     1  \r\nR2       EQU     2  \r\nR3       EQU     3  \r\nR4       EQU     4  \r\nR5       EQU     5  \r\nR6       EQU     6  \r\nR7       EQU     7  \r\nR8       EQU     8  \r\nR9       EQU     9  \r\nR10      EQU     10 \r\nR11      EQU     11 \r\nR12      EQU     12 \r\nR13      EQU     13 \r\nR14      EQU     14 \r\nR15      EQU     15 \r\n*                   \r\n         END     ,<\/pre>\n<p>Now we can compile and link edit our program. When we run the program it should wait for ten seconds and then exit.<\/p>\n<pre>JOB 6757  $HASP373 SRB01    STARTED - INIT 12 - CLASS A - SYS TCS3\r\nJOB 6757  15.42.10   0.00.10   0.00.00  0000   SRB01     MVSSP    \r\nJOB 6757  15.42.10   0.00.10   0.00.00  0000   SRB01     ######## \r\nJOB 6757  $HASP395 SRB01    ENDED<\/pre>\n<p>If we did something wrong it is very possible running this program will crash MVS. If that happens we can simply restart with an IPL and try to fix the problem.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A Service Request Block (SRB) defines a dispatchable unit of work (Service Routine) in MVS.\u00a0 A dispatchable unit of work is just a fancy way of saying some code that will be run by the dispatcher.\u00a0 A SRB as opposed to a Task Control Block is considered a lightweight task.\u00a0 This simply means it has &#8230;<\/p>\n<p><a href=\"https:\/\/tommysprinkle.com\/mvssp\/2013\/01\/01\/srb-service-request-block-overview\/\" class=\"more-link\">Continue reading &lsquo;SRB &#8211; Service Request Block Overview&rsquo; &raquo;<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[3],"tags":[],"class_list":["post-6","post","type-post","status-publish","format-standard","hentry","category-srb-overview"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p3x7AW-6","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/tommysprinkle.com\/mvssp\/wp-json\/wp\/v2\/posts\/6","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tommysprinkle.com\/mvssp\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tommysprinkle.com\/mvssp\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tommysprinkle.com\/mvssp\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/tommysprinkle.com\/mvssp\/wp-json\/wp\/v2\/comments?post=6"}],"version-history":[{"count":15,"href":"https:\/\/tommysprinkle.com\/mvssp\/wp-json\/wp\/v2\/posts\/6\/revisions"}],"predecessor-version":[{"id":65,"href":"https:\/\/tommysprinkle.com\/mvssp\/wp-json\/wp\/v2\/posts\/6\/revisions\/65"}],"wp:attachment":[{"href":"https:\/\/tommysprinkle.com\/mvssp\/wp-json\/wp\/v2\/media?parent=6"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tommysprinkle.com\/mvssp\/wp-json\/wp\/v2\/categories?post=6"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tommysprinkle.com\/mvssp\/wp-json\/wp\/v2\/tags?post=6"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}