Trailing-Edge
-
PDP-10 Archives
-
SRI_NIC_PERM_SRC_3_19910112
-
monitor/cfssrv.mac
There are 21 other files named cfssrv.mac in the archive. Click here to see a list.
; Edit= 8960 to CFSSRV.MAC on 1-Sep-88 by GSCOTT
;*Performance* Change IFNSK to IFSKP wherever possible.
; Edit= 8956 to CFSSRV.MAC on 30-Aug-88 by GSCOTT
;Fix badly formatted BUG.
; Edit= 8951 to CFSSRV.MAC on 26-Aug-88 by LOMARTIRE
;Improve BUG. documentation some more
; Edit= 8874 to CFSSRV.MAC on 10-Aug-88 by RASPUZZI
;Update BUG. documentation again.
; Edit= 8863 to CFSSRV.MAC on 21-Jul-88 by RASPUZZI
;Increase STKVAR for structure names and shutdown messages so that we don't
;trash stacks and cause ILMNRFs.
; UPD ID= 8488, RIP:<7.MONITOR>CFSSRV.MAC.19, 9-Feb-88 12:17:31 by GSCOTT
;TCO 7.1218 - Update copyright notice.
; UPD ID= 8406, RIP:<7.MONITOR>CFSSRV.MAC.18, 4-Feb-88 10:23:20 by GSCOTT
;TCO 7.1210 - Set CFCCML, CFCCDF, CFCONN, CFDISC to be not normally dumpable.
; UPD ID= 8357, RIP:<7.MONITOR>CFSSRV.MAC.17, 20-Jan-88 11:40:51 by RASPUZZI
;TCO 7.1190 - Split CFSSRV into CFSPAR, CFSUSR and CFSSRV so that we can
; obtain CREFs. Note that no functional change of CFS has
; occurred.
; UPD ID= 298, RIP:<7.MONITOR>CFSSRV.MAC.16, 16-Nov-87 15:02:50 by MCCOLLUM
;TCO 7.1138 - Do not search ENQPAR anymore; CFSSRV won't build. Call new
; routine ENQCST from CFSRSV upon a cluster state change.
; UPD ID= 260, RIP:<7.MONITOR>CFSSRV.MAC.15, 5-Nov-87 15:42:04 by LOMARTIRE
;TCO 7.1115 - Move setting of VPRTY and clearing of EQFKFL into CFSRSV
; UPD ID= 227, RIP:<7.MONITOR>CFSSRV.MAC.14, 28-Oct-87 14:24:00 by LOMARTIRE
;TCO 7.1096 - Replace CALL ENQRSV with SETOM EQCSTF to notify ENQSRV of
; cluster state change.
; UPD ID= 174, RIP:<7.MONITOR>CFSSRV.MAC.13, 20-Oct-87 18:21:15 by GSCOTT
;TCO 7.1075 - Update table of contents, repaginate a few places.
; Change mistyped TCO number 7.7012 to 7.1012.
; UPD ID= 172, RIP:<7.MONITOR>CFSSRV.MAC.12, 20-Oct-87 15:59:31 by RASPUZZI
;TCO 7.1074 - Add routine CFSNOD for usage.
; UPD ID= 158, RIP:<7.MONITOR>CFSSRV.MAC.11, 19-Oct-87 17:08:42 by LOMARTIRE
;TCO 7.1072 - Add code to support cluster-wide ENQ
; UPD ID= 61, RIP:<7.MONITOR>CFSSRV.MAC.10, 6-Aug-87 15:41:09 by LOMARTIRE
;TCO 7.1033 - Prevent PITRAP from EA.ENT with extended stack pointer
; UPD ID= 58, RIP:<7.MONITOR>CFSSRV.MAC.8, 29-Jul-87 08:20:31 by RASPUZZI
;TCO 7.1029 - Prevent CFCTNF BUGHLTs.
; UPD ID= 48, RIP:<7.MONITOR>CFSSRV.MAC.7, 23-Jul-87 08:41:07 by LOMARTIRE
;More of TCO 7.1021 - Create and use a new stack for CFSDMP
; UPD ID= 44, RIP:<7.MONITOR>CFSSRV.MAC.6, 15-Jul-87 14:49:30 by LOMARTIRE
;More of TCO 7.1021 - Really update the TOC this time!
; UPD ID= 39, RIP:<7.MONITOR>CFSSRV.MAC.5, 15-Jul-87 14:39:05 by LOMARTIRE
;TCO 7.1021 - Add code to support cluster dump facility. Update TOC.
; UPD ID= 22, RIP:<7.MONITOR>CFSSRV.MAC.4, 16-Jun-87 15:17:46 by MCCOLLUM
; TCO 7.1012 - Make CFMDSN fail if the DSN specified already exists
; for a different structure
; UPD ID= 19, RIP:<7.MONITOR>CFSSRV.MAC.3, 16-Jun-87 12:19:27 by LOMARTIRE
;TCO 7.1011 - Add cluster joining messages to CFSJYN. Also, update TOC.
; *** Edit 7464 to CFSSRV.MAC by LOMARTIRE on 29-Apr-87, for SPR #21438
; Rework CFS structure tokens and structure create/mount handling
; *** Edit 7445 to CFSSRV.MAC by LOMARTIRE on 13-Apr-87, for SPR #21307
; Use correct algorithm in CFCNCK to determine an open connection
; *** Edit 7348 to CFSSRV.MAC by LOMARTIRE on 1-Aug-86
; Prevent OPNX9 errors from stale ENQ tokens remaining on system
; *** Edit 7330 to CFSSRV.MAC by LOMARTIRE on 27-Jun-86, for SPR #21275
; Prevent CFSTUC BUGHLTs
; *** Edit 7315 to CFSSRV.MAC by LOMARTIRE on 11-Jun-86, for SPR #21144
; Prevent OPNX9 from ENQ tokens remaining after STRTAB is zeroed - for SPR
; 21144A
; *** Edit 7247 to CFSSRV.MAC by LOMARTIRE on 19-Feb-86
; Implement OFN caching
;Edit 7247 - Implement file access token caching portion of OFN caching
; *** Edit 7211 to CFSSRV.MAC by GRANT on 18-Dec-85
; Add CI counters for WATCH
; Edit 7152 to CFSSRV.MAC by GRANT on 15-Oct-85
; Don't BUGHLT if there are more than 4 KLs in the cluster.
; Remove check against CFSMAX when making a connection.
; Edit 7144 to CFSSRV.MAC by LOMARTIRE on 10-Sep-85 (TCO 6-1-1534)
; Make sure that CFS connects only to TOPS-20 hosts
; UPD ID= 2324, SNARK:<6.1.MONITOR>CFSSRV.MAC.380, 5-Sep-85 09:59:41 by LOMARTIRE
;TCO 6.1.1535 - Fix CFSBEF to use the correct transaction number
; UPD ID= 2278, SNARK:<6.1.MONITOR>CFSSRV.MAC.379, 25-Jun-85 14:58:36 by GRANT
;TCO 6.1.1473 - In CFSJYN, check for node in maintenance state
; UPD ID= 2110, SNARK:<6.1.MONITOR>CFSSRV.MAC.378, 3-Jun-85 16:14:30 by LOMARTIRE
;TCO 6.1.1374 - Make the delay time a function of the number of nodes on CI
; UPD ID= 2055, SNARK:<6.1.MONITOR>CFSSRV.MAC.376, 3-Jun-85 14:19:48 by MCCOLLUM
;TCO 6.1.1406 - Update copyright notice.
; UPD ID= 1998, SNARK:<6.1.MONITOR>CFSSRV.MAC.375, 23-May-85 14:27:36 by MCCOLLUM
;TCO 6.1.1238 - Fix more BUG. documentation
; UPD ID= 1995, SNARK:<6.1.MONITOR>CFSSRV.MAC.374, 21-May-85 12:32:12 by LOMARTIRE
;TCO 6.1.1238 - Fix more BUG. documentation
; UPD ID= 1960, SNARK:<6.1.MONITOR>CFSSRV.MAC.373, 13-May-85 09:15:29 by LOMARTIRE
;TCO 6.1.1375 - Add missing index register in BRDTIM
; UPD ID= 1867, SNARK:<6.1.MONITOR>CFSSRV.MAC.372, 4-May-85 10:53:46 by MCCOLLUM
;TCO 6.1.1238 - Fix more BUG. documentation
; UPD ID= 1809, SNARK:<6.1.MONITOR>CFSSRV.MAC.371, 24-Apr-85 14:23:31 by MCCOLLUM
;TCO 6.1.1238 - Fix more BUG. documentation
; UPD ID= 1783, SNARK:<6.1.MONITOR>CFSSRV.MAC.370, 23-Apr-85 12:30:13 by MCCOLLUM
;TCO 6.1.1238 - Fix typos in BUG. documentation
; UPD ID= 1778, SNARK:<6.1.MONITOR>CFSSRV.MAC.369, 22-Apr-85 23:12:56 by MCCOLLUM
;TCO 6.1.1238 - Fix more BUG. documentation
; UPD ID= 1763, SNARK:<6.1.MONITOR>CFSSRV.MAC.368, 17-Apr-85 14:01:57 by LOMARTIRE
;TCO 6.1.1327 - Prevent PITRAPs by locking down correct page in CFCARV
; UPD ID= 1722, SNARK:<6.1.MONITOR>CFSSRV.MAC.367, 8-Apr-85 10:43:07 by MCCOLLUM
;TCO 6.1.1238 - Fix BUG. documentation
; UPD ID= 1644, SNARK:<6.1.MONITOR>CFSSRV.MAC.366, 18-Mar-85 08:10:55 by GRANT
;More TCO 6.1.1245 - minor enhancements
; UPD ID= 1623, SNARK:<6.1.MONITOR>CFSSRV.MAC.365, 12-Mar-85 15:56:34 by LOMARTIRE
;TCO 6.1.1247 - Improve CFSJYN and update table of contents
; UPD ID= 1615, SNARK:<6.1.MONITOR>CFSSRV.MAC.364, 11-Mar-85 09:57:31 by GRANT
;TCO 6.1.1245 - Add routines CFCBRD, CHKCLC, and CFCEAS for ^ECEASE protocol
; UPD ID= 1548, SNARK:<6.1.MONITOR>CFSSRV.MAC.363, 20-Feb-85 15:26:11 by LOMARTIRE
;TCO 6.1.1200 - Add the CFSDSN routine to handle a swap of a DSN on a DSA disk
; UPD ID= 1533, SNARK:<6.1.MONITOR>CFSSRV.MAC.362, 19-Feb-85 10:33:12 by LOMARTIRE
;TCO 6.1.1207 - Calculate HSHCOD correctly in CFRDSN
; UPD ID= 1531, SNARK:<6.1.MONITOR>CFSSRV.MAC.361, 19-Feb-85 10:10:33 by LOMARTIRE
;TCO 6.1.1194 - Return an error number when returning a no vote response.
; Have the requesting side interpret this number and form a TOPS-20 error code.
; UPD ID= 1447, SNARK:<6.1.MONITOR>CFSSRV.MAC.360, 1-Feb-85 14:17:26 by LOMARTIRE
;Add new symbols to describe the priority used by SC.SMG
; UPD ID= 1440, SNARK:<6.1.MONITOR>CFSSRV.MAC.359, 31-Jan-85 16:14:56 by MOSER
;TCO 6.1.1166 - *PERFORMANCE* - OFN MANAGEMENT - CANNOT USE MAXSPL ANYMORE
; UPD ID= 1405, SNARK:<6.1.MONITOR>CFSSRV.MAC.358, 25-Jan-85 09:35:11 by WAGNER
;TCO 6.1.1155 - *PERFORMANCE* - Change HSHLEN to be Prime
; UPD ID= 1350, SNARK:<6.1.MONITOR>CFSSRV.MAC.357, 16-Jan-85 16:43:02 by MOSER
;TCO 6.1.1139 - *PERFORMANCE* - CHANGE PSKED REFS TO PSKD1
; UPD ID= 1285, SNARK:<6.1.MONITOR>CFSSRV.MAC.356, 8-Jan-85 10:09:05 by GRANT
;Change comments in header of routine CFRDSN.
; UPD ID= 1245, SNARK:<6.1.MONITOR>CFSSRV.MAC.355, 31-Dec-84 09:32:39 by LOMARTIRE
;TCO 6.1.1096 - Make ASC8T7 global for use by new .CFHSC funciton of CNFIG%
; UPD ID= 1213, SNARK:<6.1.MONITOR>CFSSRV.MAC.354, 17-Dec-84 16:30:24 by TBOYLE
;Change use of MAXNDS in CFS tables to HSTSIZ in CNFIG functions..
; UPD ID= 1192, SNARK:<6.1.MONITOR>CFSSRV.MAC.353, 12-Dec-84 09:50:56 by GRANT
;TCO 6.1.1084 - In CFDIAG, put serial number in OLDTAB so CFRECN will happen.
; UPD ID= 1055, SNARK:<6.1.MONITOR>CFSSRV.MAC.351, 13-Nov-84 09:04:51 by LOMARTIRE
;Use new sending priority symbols in SC.SMG calls.
;Rearrange CFSGET routine.
; UPD ID= 4877, SNARK:<6.MONITOR>CFSSRV.MAC.350, 25-Sep-84 14:00:01 by GRANT
;DLYTIM is now the time between loading the KLIPA and reconnecting
; UPD ID= 4862, SNARK:<6.MONITOR>CFSSRV.MAC.349, 21-Sep-84 14:00:26 by HALL
;Add documentation to CFSGFA routine
;Subtitles and comments
; UPD ID= 4782, SNARK:<6.MONITOR>CFSSRV.MAC.348, 30-Aug-84 21:58:53 by MCLEAN
;MOVE CALLS TO PYCOFF AND PYCON
; UPD ID= 4767, SNARK:<6.MONITOR>CFSSRV.MAC.347, 29-Aug-84 13:30:12 by MCLEAN
;MISSED A CALL TO CIONLT FOR BOTH PATH CHANGE
; UPD ID= 4753, SNARK:<6.MONITOR>CFSSRV.MAC.346, 26-Aug-84 21:01:41 by MCLEAN
;REMOVE PHYMPR/PHYUPR NO LONGER NEEDED
; UPD ID= 4667, SNARK:<6.MONITOR>CFSSRV.MAC.345, 8-Aug-84 15:18:34 by LOMARTIRE
;Add subtitles and table of contents
; UPD ID= 4647, SNARK:<6.MONITOR>CFSSRV.MAC.344, 7-Aug-84 10:21:58 by LOMARTIRE
;Fix handling of .SSPBC callback since now we can get an extra one.
; UPD ID= 4640, SNARK:<6.MONITOR>CFSSRV.MAC.343, 31-Jul-84 14:52:25 by PURRETTA
;Add copyright statement, remove brackets in comments.
; UPD ID= 4562, SNARK:<6.MONITOR>CFSSRV.MAC.342, 18-Jul-84 19:31:25 by HALL
;Comments
; UPD ID= 4495, SNARK:<6.MONITOR>CFSSRV.MAC.341, 12-Jul-84 19:52:27 by LOMARTIRE
;Overhaul callback table. Remove .SSCBD and replace with .SSDDG.
;Code for AC change in .SSDGR/.SSMGR callbacks.
;Remove .SSNWO and .SSMNT from callback table.
; UPD ID= 4423, SNARK:<6.MONITOR>CFSSRV.MAC.340, 3-Jul-84 14:26:05 by LOMARTIRE
;Make call to SC.RCD pass in the address of the argument block.
;Obtain block from free space since SC.RCD no longer does so.
; UPD ID= 4420, SNARK:<6.MONITOR>CFSSRV.MAC.339, 3-Jul-84 09:55:25 by HALL
;CFSJYN - Don't check on nodes until online callback
; UPD ID= 4406, SNARK:<6.MONITOR>CFSSRV.MAC.338, 28-Jun-84 13:24:53 by TBOYLE
;CNFIG% - At .CFCSE, CFCSEB does not have unused bits zeroed.
; UPD ID= 4376, SNARK:<6.MONITOR>CFSSRV.MAC.337, 22-Jun-84 16:28:26 by TBOYLE
;CNFIG% - Put CFS routines in here.
; UPD ID= 4210, SNARK:<6.MONITOR>CFSSRV.MAC.336, 11-May-84 12:14:50 by GRANT
;In CFSJYN, remove call to SRVCFS (it's now at RUNDD2 in MEXEC)
; UPD ID= 4160, SNARK:<6.MONITOR>CFSSRV.MAC.335, 1-May-84 07:35:54 by HALL
;Add Q2 to the AC's saved by CFSRTV. This was confusing SCAPOL.
; UPD ID= 4143, SNARK:<6.MONITOR>CFSSRV.MAC.334, 25-Apr-84 17:50:37 by HALL
;TRY TO GET THE IFNS RIGHT
; UPD ID= 4138, SNARK:<6.MONITOR>CFSSRV.MAC.333, 25-Apr-84 14:38:21 by HALL
;Rearrange SCA interface routines
;CFSCPS - Get rid of BLOCK. (and the bug that went with it), and use a
;subroutine to disconnect duplicate connections.
; UPD ID= 4135, SNARK:<6.MONITOR>CFSSRV.MAC.332, 25-Apr-84 13:03:05 by LOMARTIRE
;Replace all .SCFxx error codes with equivalent SCSxxx error codes
; UPD ID= 4114, SNARK:<6.MONITOR>CFSSRV.MAC.331, 24-Apr-84 12:58:40 by TGRADY
;TCO 6.2041 - ILSPTI BUGHLT's on Non-CFS monitors.
; Remove conditional assembly switches around global job numbers code
; UPD ID= 4085, SNARK:<6.MONITOR>CFSSRV.MAC.330, 15-Apr-84 10:01:36 by HALL
;Add comments and subtitles
; UPD ID= 4042, SNARK:<6.MONITOR>CFSSRV.MAC.329, 3-Apr-84 14:32:59 by LOMARTIRE
;Add node number and connect ID to CFACCF, CFCCLZ, and CFRECN BUGxxx's
; UPD ID= 3974, SNARK:<6.MONITOR>CFSSRV.MAC.328, 25-Mar-84 11:16:44 by HALL
;Add SAVET to ONLINE and OFLINE
; UPD ID= 3947, SNARK:<6.MONITOR>CFSSRV.MAC.327, 20-Mar-84 03:03:37 by HALL
;Add node number and CID to OFLINE and ONLINE
; UPD ID= 3926, SNARK:<6.MONITOR>CFSSRV.MAC.326, 14-Mar-84 13:02:05 by TGRADY
;TCO 6.1999 - Remove edit 3840, and conditionally define MXGLBS in STG
; UPD ID= 3863, SNARK:<6.MONITOR>CFSSRV.MAC.325, 7-Mar-84 05:50:00 by GRANT
;Fix CFFCTB to handle new callbacks. Clarify some comments.
; UPD ID= 3843, SNARK:<6.MONITOR>CFSSRV.MAC.324, 4-Mar-84 06:26:51 by GRANT
;Add cell CONCID in which the CID for the current connection attempt is saved.
; UPD ID= 3840, SNARK:<6.MONITOR>CFSSRV.MAC.323, 2-Mar-84 15:59:23 by TGRADY
;Correct last edit - use NJOBS, not MXGLBS, for non-CFS range check.
; UPD ID= 3836, SNARK:<6.MONITOR>CFSSRV.MAC.322, 1-Mar-84 15:22:31 by TGRADY
; Make GL2LCL still do range check even on non-cfs monitors.
; UPD ID= 3794, SNARK:<6.MONITOR>CFSSRV.MAC.321, 29-Feb-84 01:41:07 by TGRADY
; One more fix to GL2LCL for Job 0...
; UPD ID= 3777, SNARK:<6.MONITOR>CFSSRV.MAC.320, 28-Feb-84 10:32:12 by MOSER
;TCO 6.1562 - TELL MSCP SERVER WHEN TO OPEN A LISTNER
; UPD ID= 3761, SNARK:<6.MONITOR>CFSSRV.MAC.319, 26-Feb-84 23:53:49 by TGRADY
; Add LCL2GL to look up a Global Job number, given a local job index.
; UPD ID= 3748, SNARK:<6.MONITOR>CFSSRV.MAC.318, 24-Feb-84 20:59:32 by GRANT
;In LSNUP, start a new listener after rejecting an incoming connection.
;Add reporting of CFS disconnect.
; UPD ID= 3742, SNARK:<6.MONITOR>CFSSRV.MAC.317, 23-Feb-84 14:13:47 by GRANT
;STRVER is only for CFS monitors.
; UPD ID= 3722, SNARK:<6.MONITOR>CFSSRV.MAC.316, 22-Feb-84 05:37:15 by GRANT
;Add CFSJ0 to do STRVER stuff
; UPD ID= 3711, SNARK:<6.MONITOR>CFSSRV.MAC.315, 21-Feb-84 12:58:51 by CDUNN
;Change LISNAM to use a 16 byte 8 bit ASCII string. Also change calls to SC.CON
;and SC.LIS to pass the address of the string, not a byte pointer.
; UPD ID= 3678, SNARK:<6.MONITOR>CFSSRV.MAC.314, 8-Feb-84 21:50:15 by MILLER
;Remove call to STRVER for now. Put it back when job 0 knows how to call it
; UPD ID= 3668, SNARK:<6.MONITOR>CFSSRV.MAC.313, 8-Feb-84 10:05:49 by MILLER
;select the A path for the loopback message
; UPD ID= 3667, SNARK:<6.MONITOR>CFSSRV.MAC.312, 8-Feb-84 09:55:20 by MILLER
;Add STRVER and use it during CI joining
; UPD ID= 3661, SNARK:<6.MONITOR>CFSSRV.MAC.311, 7-Feb-84 16:07:27 by MILLER
;Fix CFSSMT and friends for better resolution on DSN conflicts
; UPD ID= 3748, SNARK:<6.MONITOR>CFSSRV.MAC.318, 24-Feb-84 20:59:32 by GRANT
;In LSNUP, start a new listener after rejecting an incoming connection.
;Add reporting of CFS disconnect.
; UPD ID= 3742, SNARK:<6.MONITOR>CFSSRV.MAC.317, 23-Feb-84 14:13:47 by GRANT
;STRVER is only for CFS monitors.
; UPD ID= 3722, SNARK:<6.MONITOR>CFSSRV.MAC.316, 22-Feb-84 05:37:15 by GRANT
;Add CFSJ0 to do STRVER stuff
; UPD ID= 3711, SNARK:<6.MONITOR>CFSSRV.MAC.315, 21-Feb-84 12:58:51 by CDUNN
;Change LISNAM to use a 16 byte 8 bit ASCII string. Also change calls to SC.CON
;and SC.LIS to pass the address of the string, not a byte pointer.
; UPD ID= 3678, SNARK:<6.MONITOR>CFSSRV.MAC.314, 8-Feb-84 21:50:15 by MILLER
;Remove call to STRVER for now. Put it back when job 0 knows how to call it
; UPD ID= 3668, SNARK:<6.MONITOR>CFSSRV.MAC.313, 8-Feb-84 10:05:49 by MILLER
;select the A path for the loopback message
; UPD ID= 3667, SNARK:<6.MONITOR>CFSSRV.MAC.312, 8-Feb-84 09:55:20 by MILLER
;Add STRVER and use it during CI joining
; UPD ID= 3661, SNARK:<6.MONITOR>CFSSRV.MAC.311, 7-Feb-84 16:07:27 by MILLER
;Fix CFSSMT and friends for better resolution on DSN conflicts
; UPD ID= 3657, SNARK:<6.MONITOR>CFSSRV.MAC.310, 4-Feb-84 11:33:29 by MILLER
;fix typeo
; UPD ID= 3655, SNARK:<6.MONITOR>CFSSRV.MAC.309, 4-Feb-84 10:32:23 by MILLER
;Add routine BRDTIM, to send TAD to appropriate other hosts.
; UPD ID= 3610, SNARK:<6.MONITOR>CFSSRV.MAC.308, 31-Jan-84 17:20:47 by TGRADY
; In JBGET1, don't increment & decrement the Global job number assigned. User
; gets returned the Global Job number +1 when this is done.
; UPD ID= 3594, SNARK:<6.MONITOR>CFSSRV.MAC.307, 31-Jan-84 04:04:53 by TGRADY
;Make GL2LCL RETBAD if the local job number found is out of range (1-NJOBS)
;Make JBGET1 and JBAVAL handle Job 0 (Ignore it)
; UPD ID= 3583, SNARK:<6.MONITOR>CFSSRV.MAC.306, 28-Jan-84 19:14:59 by MILLER
;Remove use of MAXVWT for now
; UPD ID= 3581, SNARK:<6.MONITOR>CFSSRV.MAC.305, 28-Jan-84 17:41:09 by MILLER
;Change MAXVWT to 1
; UPD ID= 3516, SNARK:<6.MONITOR>CFSSRV.MAC.304, 23-Jan-84 18:29:01 by MOSER
;CHANGE MSTX16 AND MSTX17 TO BE MSTX45 AND MSTX46 SO AS NOT TO CONFLICT
; WITH THE OTHER MSTX16 AND MSTX17
; UPD ID= 3501, SNARK:<6.MONITOR>CFSSRV.MAC.303, 20-Jan-84 18:29:40 by MILLER
;Add prcoessor serial number to CFONLN BUGINF
; UPD ID= 3494, SNARK:<6.MONITOR>CFSSRV.MAC.302, 20-Jan-84 11:12:46 by CDUNN
;More TCO 6.1127 - Change call to SC.LIS to not allow buffers to be queued
; UPD ID= 3458, SNARK:<6.MONITOR>CFSSRV.MAC.301, 14-Jan-84 12:43:31 by MILLER
;One more stab at drive online stuff.
; UPD ID= 3443, SNARK:<6.MONITOR>CFSSRV.MAC.300, 12-Jan-84 12:06:49 by MILLER
;Handle credit low and arrival without races
; UPD ID= 3435, SNARK:<6.MONITOR>CFSSRV.MAC.299, 11-Jan-84 10:52:35 by MILLER
; UPD ID= 3432, SNARK:<6.MONITOR>CFSSRV.MAC.298, 10-Jan-84 19:51:36 by MILLER
;More of the previous
; UPD ID= 3417, SNARK:<6.MONITOR>CFSSRV.MAC.297, 6-Jan-84 08:58:25 by MILLER
;use two-word DSNs
; UPD ID= 3401, SNARK:<6.MONITOR>CFSSRV.MAC.296, 3-Jan-84 15:28:59 by MILLER
;Add a BUGCHK to CFSRDR if directory is not locked
; UPD ID= 3395, SNARK:<6.MONITOR>CFSSRV.MAC.295, 3-Jan-84 09:55:31 by MILLER
;CFSRDR should not do ECSKED if DIRECTORY was not locked
; UPD ID= 3392, SNARK:<6.MONITOR>CFSSRV.MAC.294, 30-Dec-83 08:22:56 by MILLER
;Check for both drives the same in CFRDSN
; UPD ID= 3334, SNARK:<6.MONITOR>CFSSRV.MAC.293, 16-Dec-83 15:51:28 by MILLER
;Add CFONLN BUGINF for debugging
; UPD ID= 3300, SNARK:<6.MONITOR>CFSSRV.MAC.292, 13-Dec-83 09:10:39 by MILLER
;Enhance CFCCLZ BUGCHK to include the SCA error code
; UPD ID= 3298, SNARK:<6.MONITOR>CFSSRV.MAC.291, 13-Dec-83 08:34:55 by MILLER
;Add CFDIAG to clean up on "CI OFFLINE" call
; UPD ID= 3289, SNARK:<6.MONITOR>CFSSRV.MAC.290, 11-Dec-83 20:20:35 by GRANT
;In CFSCTH, use new symbol VC.OPN
; UPD ID= 3240, SNARK:<6.MONITOR>CFSSRV.MAC.289, 30-Nov-83 22:01:54 by MILLER
;Add "guard word" to verify VOTE packets
; UPD ID= 3236, SNARK:<6.MONITOR>CFSSRV.MAC.288, 30-Nov-83 17:39:40 by MILLER
;Previsou fix not right. Revert to old way
; UPD ID= 3233, SNARK:<6.MONITOR>CFSSRV.MAC.287, 30-Nov-83 11:24:20 by MILLER
;Fix allocation of vote packets
; UPD ID= 3211, SNARK:<6.MONITOR>CFSSRV.MAC.286, 23-Nov-83 13:36:41 by MILLER
;More work on CI error recovery
; UPD ID= 3195, SNARK:<6.MONITOR>CFSSRV.MAC.285, 18-Nov-83 15:03:44 by MILLER
;More of the previous
; UPD ID= 3194, SNARK:<6.MONITOR>CFSSRV.MAC.284, 18-Nov-83 14:35:53 by MILLER
;Add "temp" code to try out new CI error recovery. More to come!
; UPD ID= 3187, SNARK:<6.MONITOR>CFSSRV.MAC.283, 17-Nov-83 16:21:08 by CDUNN
;More TCO 6.1127 - Fix calls to SC.SMG to conform to new calling sequence
; UPD ID= 3100, SNARK:<6.MONITOR>CFSSRV.MAC.282, 4-Nov-83 16:56:47 by MILLER
; UPD ID= 3099, SNARK:<6.MONITOR>CFSSRV.MAC.281, 4-Nov-83 16:13:40 by MILLER
;Add CFSFDF entry to use from CFSUW0
; UPD ID= 3081, SNARK:<6.MONITOR>CFSSRV.MAC.280, 26-Oct-83 07:41:18 by MILLER
;CFSRTV must refuse a request if this node has a commit (HSHDLY <>0)
; UPD ID= 3080, SNARK:<6.MONITOR>CFSSRV.MAC.279, 26-Oct-83 07:16:31 by MILLER
;Must be CSKED during vote waiting
; UPD ID= 3061, SNARK:<6.MONITOR>CFSSRV.MAC.278, 24-Oct-83 10:20:03 by MILLER
;Fix typeo in CFAREM
; UPD ID= 3053, SNARK:<6.MONITOR>CFSSRV.MAC.277, 21-Oct-83 17:17:37 by MILLER
;Fix storing of node name from connect optional data
; UPD ID= 3050, SNARK:<6.MONITOR>CFSSRV.MAC.276, 20-Oct-83 16:38:22 by MILLER
;Fix bugs in previous edits
; UPD ID= 3048, SNARK:<6.MONITOR>CFSSRV.MAC.275, 19-Oct-83 18:25:13 by MILLER
;Once more. Do NODE% in proper place
; UPD ID= 3047, SNARK:<6.MONITOR>CFSSRV.MAC.274, 19-Oct-83 16:11:29 by MILLER
;Rearrange optional data so we an pass DECnet node name
; UPD ID= 3043, SNARK:<6.MONITOR>CFSSRV.MAC.273, 18-Oct-83 18:21:26 by MILLER
;Fix CFSDAU to handle temoprary entires
; UPD ID= 3035, SNARK:<6.MONITOR>CFSSRV.MAC.272, 13-Oct-83 11:54:36 by MILLER
; UPD ID= 3027, SNARK:<6.MONITOR>CFSSRV.MAC.271, 11-Oct-83 10:25:58 by MILLER
;TCO 6.1824. Add CFSPRT for IPCF to use
; UPD ID= 3018, SNARK:<6.MONITOR>CFSSRV.MAC.270, 10-Oct-83 13:44:37 by MILLER
;Change buffer count
; UPD ID= 3008, SNARK:<6.MONITOR>CFSSRV.MAC.269, 7-Oct-83 20:03:39 by MILLER
; UPD ID= 3007, SNARK:<6.MONITOR>CFSSRV.MAC.268, 7-Oct-83 18:31:25 by MILLER
; UPD ID= 2976, SNARK:<6.MONITOR>CFSSRV.MAC.267, 3-Oct-83 18:40:08 by MILLER
; UPD ID= 2951, SNARK:<6.MONITOR>CFSSRV.MAC.266, 28-Sep-83 07:11:55 by MILLER
;The last typeo
; UPD ID= 2950, SNARK:<6.MONITOR>CFSSRV.MAC.265, 28-Sep-83 05:54:32 by GRANT
;Fix typos in recent edits
; UPD ID= 2948, SNARK:<6.MONITOR>CFSSRV.MAC.264, 27-Sep-83 21:11:12 by MILLER
; UPD ID= 2946, SNARK:<6.MONITOR>CFSSRV.MAC.263, 27-Sep-83 20:48:44 by MILLER
; UPD ID= 2943, SNARK:<6.MONITOR>CFSSRV.MAC.262, 27-Sep-83 20:27:17 by MILLER
;More work for TCO 6.1806
; UPD ID= 2929, SNARK:<6.MONITOR>CFSSRV.MAC.261, 23-Sep-83 13:52:20 by MILLER
; UPD ID= 2927, SNARK:<6.MONITOR>CFSSRV.MAC.260, 23-Sep-83 10:59:38 by MILLER
;Fix typeos in previous edit
; UPD ID= 2925, SNARK:<6.MONITOR>CFSSRV.MAC.259, 23-Sep-83 10:34:05 by MILLER
;TCO 6.1806. Add TAD stuff
; UPD ID= 2923, SNARK:<6.MONITOR>CFSSRV.MAC.258, 23-Sep-83 10:05:01 by MILLER
;Add job number assigner
; UPD ID= 2893, SNARK:<6.MONITOR>CFSSRV.MAC.257, 12-Sep-83 19:53:49 by MILLER
;Turn off OFN bit in CFSUWT
; UPD ID= 2887, SNARK:<6.MONITOR>CFSSRV.MAC.256, 12-Sep-83 11:35:28 by MILLER
;Make sure always in section 1
; UPD ID= 2884, SNARK:<6.MONITOR>CFSSRV.MAC.255, 9-Sep-83 19:16:30 by MILLER
;New buffer management to avoid free space failures
; UPD ID= 2877, SNARK:<6.MONITOR>CFSSRV.MAC.254, 6-Sep-83 09:25:05 by MILLER
;More fixes to CFSSMT
; UPD ID= 2873, SNARK:<6.MONITOR>CFSSRV.MAC.253, 1-Sep-83 10:30:28 by MILLER
;fix CFSSMT
; UPD ID= 2871, SNARK:<6.MONITOR>CFSSRV.MAC.252, 31-Aug-83 15:32:11 by MILLER
; UPD ID= 2830, SNARK:<6.MONITOR>CFSSRV.MAC.251, 12-Aug-83 14:17:17 by MILLER
;prevent MONPDL in CFSDAU
; UPD ID= 2775, SNARK:<6.MONITOR>CFSSRV.MAC.250, 28-Jul-83 12:14:43 by MILLER
; UPD ID= 2774, SNARK:<6.MONITOR>CFSSRV.MAC.249, 27-Jul-83 16:22:10 by MILLER
; UPD ID= 2770, SNARK:<6.MONITOR>CFSSRV.MAC.248, 27-Jul-83 10:09:35 by MILLER
;Add check for illegal reconnect
; UPD ID= 2717, SNARK:<6.MONITOR>CFSSRV.MAC.247, 22-Jul-83 14:52:58 by MILLER
; UPD ID= 2712, SNARK:<6.MONITOR>CFSSRV.MAC.246, 20-Jul-83 16:58:19 by MURPHY
;Take out setup of MSECTB+CFSSEC because it's already done by PGRINI.
; UPD ID= 2710, SNARK:<6.MONITOR>CFSSRV.MAC.245, 20-Jul-83 09:59:36 by MILLER
;Clean up CFSCMC and pending connections in SCABRK
; UPD ID= 2697, SNARK:<6.MONITOR>CFSSRV.MAC.244, 13-Jul-83 14:22:39 by MILLER
;More editing fixes
; UPD ID= 2696, SNARK:<6.MONITOR>CFSSRV.MAC.243, 13-Jul-83 10:24:17 by MILLER
;Add commentary.
; UPD ID= 2693, SNARK:<6.MONITOR>CFSSRV.MAC.242, 11-Jul-83 17:40:35 by MILLER
;Yet more CI error recovery fixes
; UPD ID= 2681, SNARK:<6.MONITOR>CFSSRV.MAC.241, 6-Jul-83 12:56:31 by MILLER
;More fixes for CI error recovery
; UPD ID= 2679, SNARK:<6.MONITOR>CFSSRV.MAC.239, 6-Jul-83 10:09:57 by MILLER
;Add and maintain CFSCMC
; UPD ID= 2670, SNARK:<6.MONITOR>CFSSRV.MAC.238, 5-Jul-83 16:03:15 by MILLER
; UPD ID= 2654, SNARK:<6.MONITOR>CFSSRV.MAC.237, 2-Jul-83 08:37:58 by MILLER
;Must always create a CFSSTK pointer, even if CFSSCA=0
; UPD ID= 2612, SNARK:<6.MONITOR>CFSSRV.MAC.236, 21-Jun-83 09:47:07 by MILLER
; UPD ID= 2611, SNARK:<6.MONITOR>CFSSRV.MAC.235, 20-Jun-83 21:18:24 by MILLER
; UPD ID= 2591, SNARK:<6.MONITOR>CFSSRV.MAC.234, 20-Jun-83 10:05:44 by HALL
;TCO 6.1689 - Move fork tables to extended section
; Reference FKSTA2 via DEFSTR
; UPD ID= 2587, SNARK:<6.MONITOR>CFSSRV.MAC.233, 17-Jun-83 14:01:37 by MILLER
;Improve handling of HSHLNK and avoid a few bugs as well
; UPD ID= 2583, SNARK:<6.MONITOR>CFSSRV.MAC.232, 15-Jun-83 10:13:49 by MILLER
;Yet more fixes!
; UPD ID= 2582, SNARK:<6.MONITOR>CFSSRV.MAC.231, 15-Jun-83 09:31:03 by MILLER
;More fixes for dual-port devices
; UPD ID= 2576, SNARK:<6.MONITOR>CFSSRV.MAC.230, 8-Jun-83 21:35:17 by MILLER
;Improve recovery when free space queue is exhausted.
; UPD ID= 2571, SNARK:<6.MONITOR>CFSSRV.MAC.229, 8-Jun-83 14:23:03 by MILLER
;Make FILRST correct, but leave it out anyway
; UPD ID= 2570, SNARK:<6.MONITOR>CFSSRV.MAC.228, 8-Jun-83 13:35:43 by MILLER
;Remove FILRST
; UPD ID= 2569, SNARK:<6.MONITOR>CFSSRV.MAC.227, 8-Jun-83 13:29:50 by MILLER
;Don't set CFSSKC in CFSDIN
; UPD ID= 2550, SNARK:<6.MONITOR>CFSSRV.MAC.226, 1-Jun-83 07:40:17 by MILLER
;Remove CFSCFL BUGHLT
; UPD ID= 2542, SNARK:<6.MONITOR>CFSSRV.MAC.225, 31-May-83 14:03:43 by MILLER
; UPD ID= 2530, SNARK:<6.MONITOR>CFSSRV.MAC.224, 26-May-83 14:10:18 by MILLER
; UPD ID= 2529, SNARK:<6.MONITOR>CFSSRV.MAC.223, 26-May-83 14:08:57 by MILLER
;Add more BUGHLTs for whenever SCA fails
; UPD ID= 2525, SNARK:<6.MONITOR>CFSSRV.MAC.222, 26-May-83 11:56:22 by MILLER
;Fix CFSCHK to do CFONLT only after the monitor is initialized
; UPD ID= 2522, SNARK:<6.MONITOR>CFSSRV.MAC.221, 25-May-83 20:14:33 by MILLER
;Only do CI check if CFSSCA
; UPD ID= 2514, SNARK:<6.MONITOR>CFSSRV.MAC.220, 25-May-83 09:17:54 by MILLER
;Do a full CI check every five seconds
; UPD ID= 2500, SNARK:<6.MONITOR>CFSSRV.MAC.219, 23-May-83 11:14:27 by MILLER
;Remove dummy def of CIONLT
; UPD ID= 2478, SNARK:<6.MONITOR>CFSSRV.MAC.218, 17-May-83 10:24:07 by MILLER
;Account for CFSNDO skip return in CFSDEQ
; UPD ID= 2451, SNARK:<6.MONITOR>CFSSRV.MAC.217, 10-May-83 10:31:13 by MILLER
;Fix CFSOVT test on HSHBTF
; UPD ID= 2359, SNARK:<6.MONITOR>CFSSRV.MAC.216, 27-Apr-83 13:29:03 by MILLER
; UPD ID= 2356, SNARK:<6.MONITOR>CFSSRV.MAC.215, 27-Apr-83 11:43:28 by MILLER
; UPD ID= 2355, SNARK:<6.MONITOR>CFSSRV.MAC.214, 27-Apr-83 08:11:58 by MILLER
; UPD ID= 2308, SNARK:<6.MONITOR>CFSSRV.MAC.213, 19-Apr-83 20:04:35 by MILLER
;DOn't need POLCNT test - PHYKLP does it correctly
; UPD ID= 2298, SNARK:<6.MONITOR>CFSSRV.MAC.212, 17-Apr-83 18:45:49 by MILLER
;Add message statistics
; UPD ID= 2273, SNARK:<6.MONITOR>CFSSRV.MAC.211, 13-Apr-83 14:27:48 by MILLER
;TCO 1.1610. Add CFONLT
; UPD ID= 2240, SNARK:<6.MONITOR>CFSSRV.MAC.210, 12-Apr-83 12:07:16 by MILLER
;Remove dummy defs of PHYMPR and PHYUPR
; UPD ID= 2236, SNARK:<6.MONITOR>CFSSRV.MAC.209, 12-Apr-83 09:31:22 by MILLER
;Check SCAFL1 in CFSJYN to see if we should turn on dual-port disks
; UPD ID= 2235, SNARK:<6.MONITOR>CFSSRV.MAC.208, 12-Apr-83 07:12:16 by MILLER
;Fixes to CFSJYN and CFSNDU.
; UPD ID= 2232, SNARK:<6.MONITOR>CFSSRV.MAC.207, 11-Apr-83 13:22:31 by MILLER
;Fixes to CFSJYN
; UPD ID= 2223, SNARK:<6.MONITOR>CFSSRV.MAC.206, 8-Apr-83 17:33:21 by MILLER
; UPD ID= 2222, SNARK:<6.MONITOR>CFSSRV.MAC.205, 8-Apr-83 15:36:03 by MILLER
;Join only when CFSINI called AND CFSJYN called
; UPD ID= 2184, SNARK:<6.MONITOR>CFSSRV.MAC.204, 7-Apr-83 15:21:54 by MILLER
;Avoid CFSLOK at interrupt level
; UPD ID= 2169, SNARK:<6.MONITOR>CFSSRV.MAC.203, 5-Apr-83 16:23:29 by MILLER
;TCO 6.1094. Move RS defs to STG
; UPD ID= 2155, SNARK:<6.MONITOR>CFSSRV.MAC.202, 4-Apr-83 17:31:32 by MILLER
;TCO 6.1588. Make sure vote buffers are usable
; UPD ID= 2143, SNARK:<6.MONITOR>CFSSRV.MAC.201, 4-Apr-83 07:42:35 by MILLER
;TCO 6.1094. Make length of vote packets an even number of words
; COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1984, 1988.
; ALL RIGHTS RESERVED.
;
; THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
; ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH THE
; INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR ANY OTHER
; COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
; OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY
; TRANSFERRED.
;
; THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
; AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
; CORPORATION.
;
; DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF ITS
; SOFTWARE ON EQUIPMENT THAT IS NOT SUPPLIED BY DIGITAL.
SEARCH CFSPAR,PROLOG,SCAPAR,PHYPAR ;[7.1190]
TTITLE CFSSRV
EXTN <CFSSEC>
DEBUG==1 ;Do debugging
IFE CFSSCA,<CFSDUM==0> ;If no SCA, define this as a dummy as well
Subttl Table of Contents
; Table of Contents for CFSSRV
;
; Section Page
;
;
; 1. Design Notes . . . . . . . . . . . . . . . . . . . . . 7
; 2. Data Storage . . . . . . . . . . . . . . . . . . . . . 12
; 3. CFS Macro Supporting Routines . . . . . . . . . . . . 15
; 4. Initialization
; 4.1 CFSINI (SCA initialization routine) . . . . . 16
; 4.2 CFSDIN (Initialize CFS database) . . . . . . . 17
; 5. Support Routines
; 5.1 CFONLT (Test state of connection) . . . . . . 18
; 5.2 PRTOFL (Turn off dual port access) . . . . . . 19
; 5.3 PRTONL (Turn on dual port access) . . . . . . 20
; 5.4 CFSKPR (KLIPA ucode reloaded) . . . . . . . . 21
; 5.5 DEDKLP (KLIPA is dead) . . . . . . . . . . . . 22
; 5.6 CFSCTH (Connect to host) . . . . . . . . . . . 23
; 5.7 HASHN (Compute hash for resource) . . . . . . 25
; 5.8 HSHLOK (Locate hash entry for resource) . . . 26
; 5.9 GNAME (Get structure name) . . . . . . . . . . 27
; 5.10 CFSULL (Unlock CFS database) . . . . . . . . . 28
; 5.11 CFSMAP (Map entries onto function) . . . . . . 29
; 5.12 CFSRSE (Remove stale entries) . . . . . . . . 31
; 5.13 CFSSBB (Place OFN in SDB) . . . . . . . . . . 32
; 5.14 CFSWUP (General wait routine) . . . . . . . . 33
; 5.15 CFSRSV (Restart vote) . . . . . . . . . . . . 34
; 5.16 CFTADC (Get CFS time and date) . . . . . . . . 35
; 5.17 CFCNCK (Check for CFS connection to node) . . 36
; 6. Resource manager
; 6.1 CFSGET (Acquire a resource) . . . . . . . . . 37
; 6.2 CFSRMV (Remove entry from hash table) . . . . 43
; 6.3 CFSNDO (Undeclare a resource) . . . . . . . . 44
; 6.4 CFSOHS (Notify rejected hosts after undeclare) 46
; 6.5 CFSUGD (Upgrade or downgrade a resource lock) 47
; 7. The voter
; 7.1 VOTEW (Start vote and wait for results) . . . 49
; 7.2 GVOTE (Get a vote buffer) . . . . . . . . . . 56
; 8. Periodic check
; 8.1 CFSCHK (Scheduler poller) . . . . . . . . . . 57
; 8.2 SCAPOL (Process incoming SCA messages) . . . . 59
Subttl Table of Contents (page 2)
; Table of Contents for CFSSRV
;
; Section Page
;
;
; 9. Call from SCA . . . . . . . . . . . . . . . . . . . . 61
; 9.1 Message Received
; 9.1.1 SCAIN (Receive message from SCA) . . . . 62
; 9.1.2 SCMSG (Process a single received message 63
; 9.1.3 CFSRTV (Vote or seize) . . . . . . . . . 64
; 9.1.4 CFSRVT (Reply to vote) . . . . . . . . . 70
; 9.1.5 CFSRFR (Resource freed) . . . . . . . . 72
; 9.1.6 CFSOFC (OFN change) . . . . . . . . . . 73
; 9.1.7 CFSEFC (EOF received) . . . . . . . . . 74
; 9.1.8 CFTADA (Time and date arrived) . . . . . 75
; 9.1.9 CFCEAS (Cease) . . . . . . . . . . . . . 76
; 9.2 SCABRK (Node went away) . . . . . . . . . . . 81
; 9.3 LSNUP (Connect to listen) . . . . . . . . . . 82
; 9.4 Connect response available
; 9.4.1 CFSCPS (Connect response available) . . 85
; 9.4.2 CFSCPX (Disconnect duplicate connection) 88
; 9.5 CFSWDN (Write completed) . . . . . . . . . . . 89
; 9.6 CFSNDU (Node up) . . . . . . . . . . . . . . . 90
; 9.7 CFSOKS (Ok to send) . . . . . . . . . . . . . 91
; 9.8 SCACRA (Credit available) . . . . . . . . . . 93
; 10. Sending Messages
; 10.1 SCAENQ (Enqueue a SCA message) . . . . . . . . 94
; 10.2 SCASND (Send a message) . . . . . . . . . . . 95
; 10.3 SENDQ (Maintain send queue) . . . . . . . . . 97
; 11. Queuing Message Buffers
; 11.1 SCARET (Queue packet as message buffer) . . . 99
; 12. Declare a dump listener
; 12.1 CFDLSN (Declare CFS dump listener) . . . . . . 100
; 13. Declare a listener
; 13.1 CFSLSN (Declare CFS listener) . . . . . . . . 102
; 14. Connection Management
; 14.1 CHKOLD (Manage connect serial number) . . . . 103
; 14.2 CHKOL0 (Generate old/new bit) . . . . . . . . 104
; 14.3 PUTOLD (Install serial number) . . . . . . . . 105
; 14.4 CLRDLY (Clear delay bit in OLDTAB entries) . . 106
; 14.5 CHKDLY (Check for delayed entries) . . . . . . 107
Subttl Table of Contents (page 3)
; Table of Contents for CFSSRV
;
; Section Page
;
;
; 15. Directory lock resource manager
; 15.1 CFSLDR (Lock directory) . . . . . . . . . . . 108
; 15.2 CFSRDR (Unlock directory) . . . . . . . . . . 110
; 15.3 CFSDAU (Acquire allocation entry) . . . . . . 111
; 15.4 CFAFND/CFAGET (Find/Get allocation table) . . 112
; 15.5 CFASTO (Store new allocation value) . . . . . 116
; 15.6 CFAULK (Unlock allocation entry) . . . . . . . 117
; 15.7 CFAREM (Remove allocation entry) . . . . . . . 118
; 15.8 CFAUPB (Undo keep here bit) . . . . . . . . . 119
; 15.9 CFAVOK (Vote to be approved) . . . . . . . . . 120
; 15.10 CFADAR (Optional data present) . . . . . . . . 121
; 15.11 CFARMV (Voter remove entry) . . . . . . . . . 122
; 15.12 GETDBK (Find resource block) . . . . . . . . . 123
; 16. File open resource manager
; 16.1 CFSGFA (Acquire file opening locks) . . . . . 124
; 16.2 CFSFFL (Release file locks) . . . . . . . . . 126
; 16.3 CFSURA (Downgrade to promiscuous) . . . . . . 127
; 17. Frozen writer resource manager
; 17.1 CFSGWL (Get write access) . . . . . . . . . . 128
; 17.2 CFSFWL (Free write access) . . . . . . . . . . 129
; 18. BAT block resource manager
; 18.1 CFGBBS (Set BAT block lock) . . . . . . . . . 131
; 18.2 CFFBBS (Release BAT block lock) . . . . . . . 132
; 19. File access token resource manager
; 19.1 CFSGWT (Get write token value) . . . . . . . . 133
; 19.2 CFSAWP/CFSAWT (Acquire write token) . . . . . 134
; 19.3 CFSDWT (Write token revoked) . . . . . . . . . 144
; 19.4 CFSOVT (Approve sharing of OFN resource) . . . 145
; 19.5 CFSGOC (Get count of resource sharers) . . . . 146
; 19.6 CFSDAR (Optional data for access token) . . . 147
; 19.7 CFSFWT (Free write token) . . . . . . . . . . 148
; 19.8 CFSUWT/CFSCWT (Release/Cache access token) . . 151
; 19.9 CFSUNC (Uncache token) . . . . . . . . . . . . 154
; 19.10 CFSBOW (Broadcast OFN update) . . . . . . . . 156
; 19.11 CFSBEF (Broadcast EOF) . . . . . . . . . . . . 157
; 19.12 CFSBRD (Main broadcast routine) . . . . . . . 159
; 19.13 CFSFOD (DDMP force out done) . . . . . . . . . 160
; 20. Structure resource manager
; 20.1 CFSSMT (Acquire structure resource) . . . . . 164
; 20.2 CFMNAM (Register structure name) . . . . . . . 166
; 20.3 CFMDSN (Register drive serial number) . . . . 167
; 20.4 CFSSMI (Acquire structure resource) . . . . . 169
; 20.5 CFSSUG (Upgrade or downgrade mount) . . . . . 171
; 20.6 CFMDER (Mount/Dismount error) . . . . . . . . 173
; 20.7 CFSSDM (Release mount resource) . . . . . . . 174
; 20.8 CFSSDI (Release mount resource) . . . . . . . 175
; 20.9 STRVER (Structure verify) . . . . . . . . . . 177
Subttl Table of Contents (page 4)
; Table of Contents for CFSSRV
;
; Section Page
;
;
; 21. File enqueue resource manager
; 21.1 CFSENQ (Get ENQ resource) . . . . . . . . . . 179
; 21.2 CFSDEQ (Release ENQ resource) . . . . . . . . 181
; 22. ENQ Lock resource manager
; 22.1 CFEQLK (Lock ENQ database) . . . . . . . . . . 183
; 22.2 CFEQUL (Unlock ENQ database) . . . . . . . . . 185
; 23. Miscellaneous Interfaces
; 23.1 FILRST (Reset all files at startup) . . . . . 186
; 23.2 CFSERR (Illegal configuration) . . . . . . . . 187
; 23.3 CFRDSN (Read drive serial number) . . . . . . 188
; 23.4 CFSDSN (Swap drive serial number) . . . . . . 189
; 23.5 CFCBRD (Broadcast system cease) . . . . . . . 192
; 23.6 CFSDMP (Force cluster dump) . . . . . . . . . 193
; 23.7 ILLGET (Illegal return from CFSGET) . . . . . 195
; 23.8 CFSKPD (KLIPA Failure) . . . . . . . . . . . . 196
; 23.9 ONLINE (CFS connection BUGINF) . . . . . . . . 197
; 23.10 CFDISC (CFS disconnect BUGINF) . . . . . . . . 198
; 23.11 PHYNOL (Declare the disks offline) . . . . . . 199
; 24. End of CFSSRV . . . . . . . . . . . . . . . . . . . . 200
SUBTTL Design Notes
COMMENT #
This module is the Common File System (CFS) support module. It contains the CFS
protocol routines, the CFS data base support routines and the glue that makes a
system out of a bunch of machines.
The CFS support code is really a "global lock manager". The manager supports a
"named locking scheme" as follows:
A lock is a multi-part name. The first part of the name is the "root". The
remaining part of the name defines a tree structure under the root.
Locks have names, owners, state and data.
The CFS protocol uses SCA to send and receive packets.
Aside from the lock management function, this module also implements the CFS
configuration manager. It handles nodes coming into the CFS network as well as
nodes leaving the CFS network. CFSCON relies heavily on SCA to provide
up-to-date information on the physical configuration, including notification of
any configuration change.
Locks are in one of several states. First, a lock may be owned locally. In
this case, any attempts to share this lock must conform to the current level of
ownership. Second, a lock may reside on the local node, but be unowned. A
request for ownership may be granted as long as the request is equal to or less
than the current level. Finally, a lock may be unknown on the local node. In
any case where the lock cannot be immediately granted, a vote must be taken. A
vote simply is a "braodcasting" of the lock request to all other CFS nodes.
The reqeust is successful is no reply denies the request. Note this scheme has
the advantage that locks need not be permanent and no single node is ever
responsible for keeping track of a dormant lock. In principle, this will most
likely happen, but it needn't. Furthermore, there is no a priori assignment of
node to lock. This means that if the owner of a lock crashes, there is no
special error recovery method. The next node to request the lock will simply
discover that its vote is successful.
The obvious disadvantage of this scheme is that requesting a lock has a fixed
cost; the cost being the same to "create" a lock. However, if the CFS network
is small, this cost is negligible and in fact the trade-off versus an elaborate
"permanent owner" scheme is well justified.
Configurations:
The conditional assemblies control configurations as follows:
CFSDUM: This is a "reduced" CFS. This system is on the CI and uses SCA to
connect to other CI-based systems. However, this processor will not share
structures with any other system but will insure that the structures it is
using are mutually exclusive from structures used by any other CI-based TOPS-20
system. This implies that this system will establish connections to other
reduced or full CFS systems and will participate in strcuture mounting votes.
CFSSCA: If zero, this processor is not on a CI with any other processor. SCA
may be in the monitor, but the CFS SYSAP is not present. This processor offers
no assurances that it will not interfere with any other CI activity. If this
is zero, CFSDUM will be defined. If this is a one, CFSDUM is defined
independently of this conditional. If CFSSCA=0, then this should processor
should either not be on a CI at all, or should be on a CI with no other TOPS-20
host systems. Any other configuration is unsupported and not likely to operate
correctly.
In addition, the CFS network number, MYPOR2, defines the CFS subnet that this
processor is in. This value is only significant if CFSSCA=1 and CFSDUM is not
defined.
The tables CFSHST, CFSHNM, and CFHSTS describe the states of the connections to
the other nodes, and one listener. The following indicates the contents of
these tables are various stages in the life of a connection.
CFSHST CFSHNM CFHSTS
Unused 0 - -
After CFSCTH SBI,,-1 -1 0
At CFSCPS if close 0 -1 0
At CFSCPS if open CID serial -1,,type
After CFSLSN -1 CID 0
After CFDLSN -2 CID 0
After LSNUP if reject 0 CID 0
After LSNUP if accept CID serial 0,,type
After CFSOKS if disc. 0 serial 0,,type
After CFSOKS if conn. CID serial -1,,type
After SCABRK 0 - -
Popular combinations
Fully open CID serial -1,,type
Listener -1 CID 0
Dump Listener -2 CID 0
Connection requested SBI,,-1 -1 0
Waiting for OKS CID serial 0,,type
The parts of CFHSTS:
L.H.
-1 when fully open
0 when being opened
1B0 turned off when disconnect happens and interlock is set
1B17 turned off to indicate lack of credit
R.H. is type:
-1 full CFS node
0 not full CFS node
Deciding what to disconnect when there is a conflict:
Connect response available (our initiator):
We're lower: close new one (our initiator)
They're lower: close already open one (their initiator)
Connect to listener (our listener):
We're lower: accept connection, wait for OK to send
They're lower: reject connection
OK to send (our listener):
We're lower: close already open one (our initiator)
They're lower: close new one (their initiator)
Major routines for managing resources:
File open CFSGFA CFSFFL
Frozen writer of file CFSGWL CFSFWL
File access token CFSAWT CSFAWP
Directory lock CFSLDR CFSRDR
Directory allocation CFSDAU
Structure mounting CFSSMT CFSSDM CFSSUG
File enqueue CFSENQ CFSDEQ
BAT blocks CFGBBS CFFBBS
Unique code:
Outgoing vote: HSHUNQ --> CFUNQ
Incoming request to vote: CFUNQ --> HSHVVL
Outgoing response to request to vote: CFUNQ(in) --> CFUNQ(out)
#
SUBTTL Data Storage
;Note: The trailing space are required by SCA. The string must be 16 bytes
;padded with spaces as necessary.
LISDMP: ASCI8 (<LCS20$CFS$DUMP >) ;[7.1021] The name of our dump listener
LISNAM: ASCI8 (<LCS20$CFS >) ;Our name
RS DMPSTK ;[7.1021] The address of the dump stack
RS DMPSVP ;[7.1021] The stack at the time of the dump
;Descriptions of this node. First offset contains serial number
IFDEF CFSDUM,< ;If we are to be a dummy
RS MYPORT,4 ;Both of these are zero
> ;IFDEF CFSDUM
IFNDEF CFSDUM,< ;If we are for real
RSI MYPORT,<0,<-1,,0>,0,0,-1> ;Make it so
> ;IFNDEF CFSDUM
MYPOR1==:MYPORT+1 ;type,, net number
MYPOR2==:MYPOR1+1 ;name
MYPOR3==:MYPOR2+1 ;rest of name + old/new flag
MYPOR4==:MYPOR3+1 ;Our CI node number
RSI CFSIFL,<-2> ;Init init flag
TIMSE0==^D600/5 ;Ten minutes of five second chunks
RSI CFSTTM,<TIMSE0> ;Full scheduler check time
IFN CFSSCA,< ;If SCA is around
RS CONCID,1 ;CID FOR CURRENT CONNECTION ATTEMPT
RS OLDTAB,1
RS DLYLOK,1 ;Word to do delay stuff
RSI DLYTIM,<^D5000> ;Delay time on CI failure per node
;RS DLYFLG,1 ;Flag to say if delay being honored
> ;IFN CFSSCA
NSPCQ==5 ;NUMBER TO PREALLOCATE
IFNDEF CFSDUM,< ;For a full CFS, get lots of packets
NSPCQ0==:^D600 ;[7.1190] Number to stack from private stock
> ;IFN CFSDUM
IFDEF CFSDUM,< ;For a reduced CFS
NSPCQ0==:^D150 ;[7.1190] Just get a few for allocation entries
> ;IFDEF CFSDUM
NSPCQ1==:^D250 ;[7.1190] Number of long packets to get
RS CFNXPG,1 ;Page pool address
RSI CFNXSZ,<PGSIZ> ;Space available in pool
RS CFTADL,1 ;Time and date cell
;Start of a long block. Remaining words are bit mask of waiting forks.
HSHDRI==:1+<NFKS+^D35>/^D36 ;[7.1190] Additional words for dir locks
WRDHSH==:NSPCQ0*HSHSIZ ;[7.1190] Words in hash packets
LNGHSH==:NSPCQ1*<HSHSIZ+HSHDRI> ;[7.1190] Words in long packets
REPEAT 0,<
RESOURCE ROOT QUALIFIER
file open str. name XB address
frozen writer str. name XB address + FILEWL
file access (OFN) str. name XB address + FILEWT
directory lock str. name directory no. + DRBASE
directory allocation str. name directory no. + DRBAS0
structure name str. alias STRCTN
drive serial no. serial no. STRCTK + high order D.S.N.
file enqueue str. name XB address + FILEEQ
BAT blocks str. name -1
RESOURCE HSHCOD
file open --
frozen writer --
file access (OFN) OFN
directory lock DRBASE
directory allocation --
structure name Drive serial no. words XORd
drive serial no. Structure alias
file enqueue --
BAT blocks --
>
SUBTTL CFS Macro Supporting Routines
;Routine to test for a structure being part of CFS or being local
;to this host.
; T1/ STR index
;Returns:
; +1 is local
; +2 is shared
RMT.TS: PUSH P,T1 ;Save STR index
MOVE T1,STRTAB(T1) ;Get SDB address
TMNE STEXL,(T1) ;Local?
JRST PA1 ;Yes
POP P,T1 ;No
RETSKP
;Routine to save P1-P5
SAVP5: ADJSP P,5 ;Get five locs
DMOVEM P1,-4(P) ;Save
DMOVEM P3,-2(P) ;Save some more
MOVEM P5,0(P) ;Finish it up
CALL 0(CX) ;And return
SKIPA
AOS -5(P) ;Skip return
DMOVE P1,-4(P) ;Restore
DMOVE P3,-2(P) ;Some more
MOVE P5,0(P) ;The rest
ADJSP P,-5 ;Clean up the stack
RET ;And done
SUBTTL Initialization -- CFSINI (SCA initialization routine)
;SCA Initialization routine for CFS code.
;If MEXEC has not yet called CFSJYN, this call to CFSJYX won't do much.
CFSINI::
IFN CFSSCA,<
CALL CHKCFS ;Verify the UCODE
CALL CFSJYX ;See if we need to join the network
> ;IFN CFSSCA
RET ;Done
SUBTTL Initialization -- CFSDIN (Initialize CFS database)
;Routine to intialize CFS data base. Called from CFSCSC
CFSDIN::
IFN CFSSCA,<
ISB SCDCHN ;And get its attention
> ;IFN CFSSCA
SETOM ALCLOK ;INIT CFS allocation lock
XMOVEI T1,SCAQ ;Get head of queue
MOVEM T1,SCTAIL ;Init queue
MOVSI T1,CFSSEC ;form address of hash table
MOVEM T1,CFHSHT ;Store it
MOVE T1,APRSER ;GET SERIAL NUMBER
LSH T1,4 ;Use left-most 32 bits
MOVEM T1,MYPORT
RET ;And done for now
SUBTTL Support Routines -- CFONLT (Test state of connection)
;Routine to test state of network connection. Called from the scheduler
;on demand
CFONLT::
IFN CFSSCA,< ;If SCA is around
SETZ T1,0 ;Either path
CALL CIONLT ;Check out the port
CALL DEDKLP ;Oops.
> ;IFN CFSSCA
RET ;Done
SUBTTL Support Routines -- PRTOFL (Turn off dual port access)
;Routines to diddle state of the dual-port access
;Turn it off if necessary
PRTOFL:
IFN CFSSCA,< ;Only if real CFS
SETOM SCAFL1 ;remember we did this
> ;IFN CFSSCA
RET ;And done
SUBTTL Support Routines -- PRTONL (Turn on dual port access)
;Turn it back on
PRTONL:
IFN CFSSCA,<
SETZM SCAFL1 ;It's clear
> ;IFN CFSSCA
RET
SUBTTL Support Routines -- CFSKPR (KLIPA ucode reloaded)
;Routine called when KLIPA UCODE is reloaded
CFSKPR::
IFN CFSSCA,< ;If a full CFS
;CALLRET DEDKLP ;Then we are in trouble
>
IFE CFSSCA,<RET> ;If not a full CFS
SUBTTL Support Routines -- DEDKLP (KLIPA is dead)
DEDKLP:
SETZM CFSTIM ;Make sure poller works soon
; TMNN SCCNC ;Anybody ever out there?
SKIPE SCAFL1 ;Already off?
IFSKP. <CALLRET PRTOFL> ;If allowable
RET
SUBTTL Support Routines -- CFSCTH (Connect to host)
IFN CFSSCA,< ;Only if supporting SCA interface
;Routine to connect to a host.
; T1/ SBI
;Returns:
; +1 couldn't send message
; +2 connet request sent. T1/ Host number of connect
CFSCTH: SAVEQ ;Get some work regs
MOVEI Q2,0(T1) ;Copy SBI
MOVE T1,[XWD .RESP1,.RDLEN] ;Priority,,length of free space
MOVEI T2,.RESGP ;Get space from resident free pool
CALL ASGRES ;(T1,T2/T1) Obtain block
RETBAD() ;Error - could not get a free space block
BLCAL.(SC.RCD,<<Q2>,<T1>>) ;Get config data
IFNSK. ;No. Forget it then
EXCH T1,T2 ;Get block address and save error code
CALL RELRES ;(T1) Return block to pool
MOVE T1,T2 ;Get error code
RETBAD() ;Return failure
ENDIF.
LOAD Q3,RDVCST,(T2) ;GET VC STATE
CAIN Q3,VC.OPN ;[8960] Open?
IFSKP. ;[8960] No. Forget it then
MOVE T1,T2 ;Get block address
CALLRET RELRES ;[8960] (T1) Return block to pool and return
ENDIF.
MOVE Q3,.RDDST(T2) ;[7144] Get destination software type
MOVE T1,T2 ;Get block address
CALL RELRES ;(T1) Return block to pool
CAME Q3,[BYTE (8) "T","-","2","0"] ;[7144] Is this a TOPS-20 node?
RETBAD() ;No. Can't be running CFS then
MOVSI Q1,-HSTSIZ ;Size of host table
PIOFF ;Own machine for a bit
DO.
SKIPN CFSHST(Q1) ;This one free?
EXIT. ;If so, use it
AOBJN Q1,TOP. ;Scan them all
PION ;Oops. None free
RETBAD() ;Can't do it
ENDDO.
HRLOM Q2,CFSHST(Q1) ;Store SBI
SETOM CFSHNM(Q1) ;Indicate doing connect
SETZM CFHSTS(Q1) ;INIT status
PION ;And allow others to proceed
MOVEI T2,0(Q1) ;Index into table
AOS CFSCMC ;Note we are doing a connect
BLCAL. (SC.CON,<<.,LISNAM>,<.,LISNAM>,Q2,[SCRDIT],[RCRDIT],<.,CFSINT>,T2,<.,MYPORT>,[BUFSCT],[0]>) ;[7.1190] Do connect
IFNSK.
SETZM CFSHST(Q1) ;Didn't make it
SETZM CONCID
SOS CFSCMC
RETBAD()
ENDIF.
MOVEM T1,CONCID ;SAVE THE CID
MOVEI T1,0(Q1) ;Get index we used
RETSKP ;OK.
> ;IFN CFSSCA
SUBTTL Support Routines -- HASHN (Compute hash for resource)
;ROUTINE TO COMPUTE HASH FOR NUMBERED RESOURCES
; T1/ROOT NUMBER
; T2/ QUALIFIER NUMBER
;RETURNS:
; +1 ALWAYS. T1=HASH
HASHN: TSC T1,T2 ;Combine them
IDIVI T1,HSHLEN ;DO MOD FUNCTION
MOVM T1,T2 ;GET RESIDUE
RET ;AND DONE
SUBTTL Support Routines -- HSHLOK (Locate hash entry for resource)
;ROUTINE TO LOOK FOR A HASH ENTRY IN A TABLE FOR A NUMBERED RESOURCE
; T1/ ROOT NUMBER
; T2/ QUALIFER
;RETURNS:
; +1 NOT FOUND AC1/ POINTER TO ENTRY POINT
; +2 FOUND. AC1/ PTR TO ENTRY
; AC2/ PREVIOUS ENTRY
;Clobbers T1 and T2 only
HSHLOK: SAVEQ
DMOVE Q1,T1 ;Save args
IFN DEBUG,< ;If debugging
TMNN VSECNO,0(P) ;Make sure this is a non-zero section
BUG.(HLT,CFSSEZ,CFSSRV,SOFT,<CFSSRV - Section 0>,,<
Cause: HSHLOK was called from section zero. HSHLOK must be called from a
non-zero section. Examine the stack and change the caller of HSHLOK to
run in a non-zero section.
>)
> ;IFN DEBUG
CALL HASHN ;GET HASH
ADD T1,CFHSHT
DO.
SKIPN Q3,(T1) ;ANYTHING HERE?
RET
;HAVE A NEW ENTRY TO EXAMINE
MOVE T2,T1
MOVE T1,Q3
CAMN Q1,HSHROT(Q3) ;This match?
CAME Q2,HSHQAL(Q3) ;Yes, this one too?
LOOP. ;NO
ENDDO.
RETSKP ;YEP. ALL DONE THEN
SUBTTL Support Routines -- GNAME (Get structure name)
;Routine to get the structure name given a structure number
; T1/ structure number
;Returns: +1 always. Sixbit name in T1
;Clobber only T1
GNAME: MOVE T1,STRTAB(T1) ;Get SDB address
SKIPE SDBALS(T1) ;An alias?
SKIPA T1,SDBALS(T1) ;Yes. Get it
MOVE T1,SDBNAM(T1) ;No. Use physical name
RET
;variant of above using AC2
GNAME2: PUSH P,T1
MOVE T1,T2
CALL GNAME
MOVE T2,T1
CALLRET PA1 ;Done
SUBTTL Support Routines -- CFSULL (Unlock CFS database)
;Called when CFSULK is done
;Returns: +1 always
CFSULL::
IFN CFSSCA,< ;If SCA present
SOSE SCAILK ;[8960] Last one?
IFSKP. ;[8960] If so.
TMNN SCWKP ;Any need to action?
SKIPE SCAQ ;No. Anything here?
ANNSK. ;If so
SAVET ;Save vulnerable regs
CALL CFSCH1 ;Yes. Do a check pass now
ENDIF.
OKSKED ;Allow scheduling now
> ;IFN CFSSCA
IFE CFSSCA,< ;If no SCA
SKIPG SCAILK ;Need to undo a lock?
IFSKP. ;If so
SOS SCAILK ;Do it
OKSKED ;And fix scheduler interlock
ENDIF.
> ;IFE CFSSCA
RET
SUBTTL Support Routines -- CFSMAP (Map entries onto function)
;Routine to map selected entries onto a function.
; T1/ mask
; T2/ comparator
; T3/ routine to call on match. Must be a "global address"
; T4/ monitor match,, count match
;This routine computes <mask AND cfscod> for each entry
;with the proper count. If the result matches the comparator,
;the routine is called.
;The coroutine in T3 is called:
; T1/ Resource block
; All Ps are preserved into the coroutine
;Call with CFSLOK or from interrupt left unlocked. Returns same
;Returns:
; +1 Stop mapping and return
; +2 continue
CFSMAP::ASUBR <AC1,AC2,AC3,AC4> ;SAVE INCOMING ARGS
SAVEQ ;SAVE REGS
MOVEI Q3,HSHLEN ;LENGTH OF THE HASH TABLE
MOVE Q1,CFHSHT ;GET TO BASE OF HASH TABLE
;LOOK FOR A HASH CHAIN
CFSMP0: SKIPN Q2,0(Q1) ;ANYTHING HERE?
JRST CFSMP1 ;NO
;FOUND A CHAIN TO START ON
CFSMP2: HLRZ T1,HSHROT(Q2) ;SEE IF USER OR MONITOR
MOVE T4,AC4 ;GET MATCH TYPES
TLNN T4,-1 ;WANT A FILTER?
JRST CFSMP5 ;NO. ALL OF THEM THEN
SKIPG T4 ;MONITOR?
JRST [ JUMPE T1,CFSMP4 ;YES. IS IT?
JRST CFSMP5] ;YEP
JUMPN T1,CFSMP4 ;NO.
CFSMP5: TRNE T4,-1 ;ANY MATCH?
JRST CFSMP3 ;YEP
JN HSHCNT,(Q2),CFSMP4 ;NO. MUST BE ZERO
CFSMP3: MOVE T1,AC1 ;GET AND MASK
AND T1,HSHCOD(Q2) ;DO AND
CAME T1,AC2 ;IS THIS IT?
JRST CFSMP4 ;NO. DON'T USE IT
;FOUND A MATCH
MOVE T1,Q2 ;COPY BLOCK
MOVE Q2,HSHLNK(Q2) ;DO COPY NOW IN CASE IT IS REMOVED
CALL @AC3 ;DO THE CALL
RET ;All done.
SKIPA
;WALK THE CHAIN
CFSMP4: MOVE Q2,HSHLNK(Q2) ;NEXT ONE
JUMPN Q2,CFSMP2
;HERE WHEN CHAIN IS DONE
CFSMP1: SOJLE Q3,R ;If seen them all, done
AOJA Q1,CFSMP0 ;DO THEM ALL
SUBTTL Support Routines -- CFSRSE (Remove stale entries)
;Maintenance routine called periodically to remove stale entries
;from the hash table.
;This routine scans the resources now held locally and removes
;any unused ones that have been dormant for a "long time". Currently,
;a "long time" is two minutes.
;OFN "access tokens" are never considered stale!
CFSRSE: MOVE T1,IRJAV ;GET LOAD AVG.
CAILE T1,^D10
MOVEI T1,^D10
IMULI T1,^D15000 ;PURGE BASED ON LAOD AVG.
MOVEI T2,SKDCNT ;Max number to release this pass
CFSRSX::SAVEAC <P1,P2> ;GET WORK REGS
MOVE P1,TODCLK ;GET NOW
SUB P1,T1 ;AGE CUTOFF
SKIPG P2,T2 ;COPY COUNT
MOVX P2,<377777,,0> ;GET A BIG NUMBER
SETZB T1,T2 ;NO MASK, MATCH ALL
XMOVEI T3,CFSRS0 ;WHERE TO GO
SETZM T4 ;ONLY UNUSED ONES PLEASE
CFSLOK ;Lock up the lock
CALL CFSMAP ;DO IT
CALLRET CFSFAL ;And done
;Routine called when an entry is located
CFSRS0: JN <HSHUGD,HSHKPH,HSHWVT,HSHTAM>,(T1),RSKP ;[7.1029] If voting, forced here or cached, then keep it
IFN DEBUG,< ;If debugging
TMNE HSHCNT,(T1) ;A debugging check!!!!
BUG.(HLT,CFSMPB,CFSSRV,SOFT,<CFSSRV - CFSMAP returned in-use entry>,,<
Cause: CFSMAP has returned a resource block that is already in use. This bug
is a debugging check.
>)
> ;IFN DEBUG
TMNN HSHLKF,(T1) ;Locked?
CAMGE P1,HSHTIM(T1) ;TOO OLD?
IFSKP.
CALL CFSRMX ;YES, REMOVE IT
SOJLE P2,R ;IF HIT LIMIT, ALL DONE
ENDIF.
RETSKP ;AND DONE
SUBTTL Support Routines -- CFSSBB (Place OFN in SDB)
;Routine called when the bit table for a structure is opened and
;the OFN is about to be placed in the SDB.
; T1/ OFN
; T2/ STR #
;Returns: +1 always.
; Preserves all temps
CFSSBB::
IFE CFSSCA,<RET> ;If no SCA, nothing to do
IFN CFSSCA,< ;If SCA
SAVET ;Save args
MOVE T3,T2 ;STR #
ADD T3,CFSSTR ;The entry in the STR table
SETZM 0(T3) ;No transactions yet
ADD T1,CFSOFN ;Find the OFN in the OFN table
CFSLOK
SKIPN T1,0(T1) ;Get it
IFSKP.
SETONE HSHBTF,(T1) ;Note this is a BT
SETZM HSHOP1(T1) ;No data here as yet
SETZM HSHOPT(T1)
ENDIF.
CALLRET CFSFAL ;And done
> ;IFN CFSSCA
SUBTTL Support Routines -- CFSWUP (General wait routine)
;General purpose wait routine. Used to select kind of wait to use
; T1/ scheduler test word
; T2/ Block address, if appropriate
CFSWUP: MOVE CX,FORKX ;Get fork handle
STOR T2,FKST2,(CX) ;Save block address
SKIPN NSKED ;NOW NOSKED?
IFSKP.
RDISMS ;IF SO, USE SPECIAL TEST
NOSKED
ELSE.
HDISMS
ENDIF.
RET ;AND DONE
SUBTTL Support Routines -- CFSRSV (Restart vote)
IFN CFSSCA,< ;Only need this with SCA present
;Routine to set "restart vote" when a node leaves the CFS net.
;This scans the active connections setting the proer bit.
;Call either CFSLOK or from interrupt level without being locked
CFSRSV: SAVET
IFN CLEQIN,< ;[7.1072]
CALL ENQCST ;[7.1138] Notify ENQSRV of cluster state change
> ;[7.1072]
SETZB T1,T2 ;MATCH ALL
XMOVEI T3,CFSRVC
MOVEI T4,-1
CALLRET CFSMAP ;DO IT
;The coroutine for above.
CFSRVC: JE HSHWVT,(T1),RSKP ;IF NOT WAITING, ALL DONE
SETONE HSHVRS,(T1) ;MAKE IT RESTART
RETSKP ;AND DONE
> ;IFN CFSSCA
SUBTTL Support Routines -- CFTADC (Get CFS time and date)
;Routine to return CFS TAD if known.
; CALL CFTADC
;Returns: +1 unknown
; +2 T1/ TAD
CFTADC::SKIPN T1,CFTADL ;have one?
RET ;No
SETZM CFTADL ;Clear it
RETSKP ;Yes
SUBTTL Support Routines -- CFCNCK (Check for CFS connection to node)
;Routine used during CI joining to check if we have a
;CFS connection to a specified node.
;
;Accepts: T1/ node number
;
;Returns: +1: No CFS connection
; +2: CFS connection exists
CFCNCK::SKIPN CFSHCT ;Get count of hosts
RET ;No connections yet
MOVEM T1,T4 ;Save node number
MOVSI T3,-HSTSIZ ;Size of host table
DO.
SKIPE T1,CFSHST(T3) ;[7445] Is there a CID for this host offset?
SKIPL CFHSTS(T3) ;[7445] Is it fully active?
IFSKP. ;A valid one did exist
CALL SC.NOD ;(T1/T1,T2) Get node number for this CID
IFGE. T2 ;[8960] A valid CID?
CAMN T4,T2 ;Is this the CID for the desired node?
RETSKP ;Yes, return success
ENDIF.
ENDIF.
AOBJN T3,TOP. ;Try next host table entry
ENDDO.
RET ;Node not found - return failure
SUBTTL Resource manager -- CFSGET (Acquire a resource)
;ROUTINE TO ACQUIRE A RESOURCE
; T1/ POINTER TO REQUEST BLOCK
; T2/ 0=) return if failed
; 1=) retry until successful
;Returns:
; +1 failed.
; T2=-1 An error occurred in which this system knows about
; the resource already and there is a conflict on
; this system. No vote has been sent out.
; T2>0 This system did not know about the requested resource
; so a vote was sent out to ask for permission to it.
; A system told us NO and the first reason for the NO
; (found in HSHDRC) is returned.
;
; +2 succeeeded.
; T1=0 =) Block is now owned by CFS server. Block
; returned to free pool owner. We linked
; the block passed in.
; T1<>0=) Block is returned as part of operation.
; We found a queued resource block and used it.
; Block passed in must be returned by caller.
;entry to figure out out if this is local or not.
;Same as above, but T3/ STR #
CFSGTT: MOVE T3,STRTAB(T3)
TMNE STEXL,(T3) ;Shared or exclusive?
JRST CFSGTL ;Don't need to vote. We have it exclusively.
JRST CFSGET ;Do need to vote.
;CFSGET is main entry point for resource manager. Call CFSGTL is
;resource is known to be exclusive to this processor.
;Entry for local lock only (caller must verify higher-level interlock)
CFSGTL::SETZRO <HSHYES,HSHWVT>,(T1)
TDZA T3,T3 ;Entry type is local
CFSGET::MOVEI T3,1 ;Entry type is remote (have to vote)
SAVEQ
STKVAR <EFLAG,RTYFLG,NSFLAG> ;HOLD RETRY FLAG HERE
MOVEM T3,EFLAG ;Save entry flag
MOVE Q1,T1 ;SAVE BLOCK ADDRESS
MOVEM T2,RTYFLG ;SAVE FLAG
MOVE T3,FORKX ;FORK HANDLE
STOR T3,HSHFRK,(Q1) ;Store it
; ..
;Here to start getting the resource.
;Also enter here from CFSGTX if retry was specified and wait is up.
CFSGT2: CFSLOK ;PROTECT DATABASE
DMOVE T1,HSHROT(Q1) ;GET ARGS.
CALL HSHLOK ;SEE IT WE KNOW ABOUT THIS ALREADY
JRST CFSGT0 ;DON'T KNOW ABOUT IT YET
;Here if we already have it. Check if access is legit.
;At this point:
; T1/ Address of queued resource block
; Q1/ Address of new resource block
CAMN T1,Q1 ;ARE WE ONE AND THE SAME?
JRST CFSG00 ;YES. ASSUME WE ARE VOTER THEN
JN <HSHWVT>,(T1),CFSGTX ;IF VOTING, FAIL
;Not waiting. Therefore we own it.
LOAD T3,HSHTYP,(Q1) ;GET REQUEST TYPE
LOAD T2,HSHTYP,(T1) ;GET TYPE WE OWN
CAIN T2,0(T3) ;ARE THEY THE SAME
JRST CFSGOD ;YES. IT MIGHT SUCCEED THEN
JN HSHCNT,(T1),CFSGTX ;NOT THE SAME. IF IN USE, FAIL
CALL CFSRMV ;NOT IN USE. WE MIGHT BE ABLE TO GET IT
JRST CFSGT1 ;NOW VOTE ON IT
;Request and owner type match. Make sure we can seize it
CFSGOD: TMNN HSHCNT,(T1) ;[8960] Unclaimed?
IFSKP. ;[8960] If not
CAIE T3,.HTOEX ;DO we want exclusive access?
ANSKP. ;If so
JE HSHLCL,(T1),CFSGTX ;If not local exclusive, lose
ENDIF.
MOVE T3,FORKX ;Get fork handle
;Accesses match and we can have it.
STOR T3,HSHFRK,(T1) ;New owner of this block
INCR HSHCNT,(T1) ;DO IT
MOVE T2,TODCLK ;GET NOW
MOVEM T2,HSHTIM(T1) ;STAMP IT
MOVE T1,Q1 ;DON'T NEED THE BLOCK ANYMORE
CALLRET CFSRSK ;RETURN GOOD
; ..
;Can't honor the request just now.
CFSGTX: SKIPE RTYFLG ;[8960] Want to retry?
IFSKP. ;[8960] If not
MOVE T1,Q1
CALL @HSHRET(T1) ;Release the block
SETOM T2 ;Conflict on this system. No reason code.
CALLRET CFSFAL ;And done
ENDIF.
;Here if caller specified retry until successful.
;Wait for a bit, and try again.
;At this point:
; T1/ Address of queued resource block of owner or voter (zero if none)
; Q1/ Address of new resource block
IFN. T1 ;IF THERE IS A LOCK NOW
TMNN HSHLOS,(T1) ;LONG BLOCK?
ANSKP. ; If so
MOVE T2,FORKX
IDIVI T2,44
MOVE T3,BITS(T3)
ADD T2,T1
IORM T3,HSHBTT(T2) ;SET WAITING BIT IN ORIGINAL BLOCK
ENDIF.
SKIPN T1,HSHWTM(Q1) ;Any wait time given?
MOVEI T1,^D1000 ;If not, use 1 sec
CAIGE T1,^D20 ;A reasonable time?
MOVEI T1,^D20 ;No. So make it so
ADD T1,TODCLK ;Compute wakeup time
MOVEM T1,HSHTIM(Q1) ;SAVE IT FOR LATER
SETZRO HSHVRS,(Q1) ;NEED THIS
CFSULK
MOVE T2,Q1 ;Save block address
MOVEI T1,CFSRWT
CALL CFSWUP ;DO A WAIT
SETZRO <HSHRTY,HSHVRS>,(Q1) ;NO RETRY NOW
JRST CFSGT2 ;TRY AGAIN
;Sheduler test for above
CFSRWT: LOAD T1,FKST2,(Q3)
DMOVE T1,HSHROT(T1) ;GET HASH VALUES
CALL HSHLOK ;LOOK IT UP
JRST 1(4)
JN HSHLSG,(T1),0(4) ;IF STILL BEING RELEASED, WAIT
OPSTR <CAMN T1,>,FKST2,(Q3) ;ARE THE TWO BLOCKS THE SAME?
JRST [ MOVE T2,HSHTIM(T1) ;GET AWAKE TIME
TMNN <HSHVRS,HSHRTY>,(T1) ;IF ANY RESTART CONDITIONS
CAMG T2,TODCLK ;TIME UP YET?
JRST 1(4) ;YEP
JRST 0(4)] ;NOPE
LOAD T2,FKST2,(Q3) ;GET BLOCK WE ARE WAITING FOR
JN HSHWVT,(T1),0(4) ;IF NOT THE SAME, AND VOTING, GIVE UP
TMNN HSHCNT,(T1) ;ANY USERS?
JRST 1(4) ;NO
LOAD T3,HSHTYP,(T2)
CAIN T3,.HTOEX ;TRYING FOR EXCLUSIVE USE?
JRST 0(4) ;YES. MUST WAIT SOME MORE THEN
OPSTR <CAME T3,>,HSHTYP,(T1) ;DO THEY NOW MATCH?
JRST 0(4) ;NO. WAIT SOME MORE
JRST 1(4) ;YES. TRY TO GET IT
;Here if we don't have the request queued. Must ask for it.
;Enter CFSGT1 when we have found a queued block on the system which was not
;in use and the access was not the same as what we desire. So, we have
;removed it. Now we will use the new block we passed into CFSGET.
CFSGT1: DMOVE T1,HSHROT(Q1) ;LOOK IT UP AGAIN
CALL HSHLOK ;We should not find it again
SKIPA
JRST CFSGTX ;Old block should have been removed!!
;First make an entry so we can remember we are doing this.
; T1/ POINTER TO PLACE TO MAKE AN ENTRY
CFSGT0: MOVEM Q1,HSHLNK(T1) ;ENQUEUE IT
MOVEM T1,HSHBKP(Q1) ;And point back as well
SETZM HSHLNK(Q1) ;And not next for this one
;Here to actually vote for the resource in an attempt to obtain it.
;No vote is required for a local exclusive resource (EFLAG = 0).
CFSG00: LOAD T1,HSHTYP,(Q1) ;TYPE WE ARE VOTING ON
SKIPE EFLAG ;Remote or local?
CALL VOTEW ;Remote, VOTE AND WAIT
JN HSHYES,(Q1),CFSGT3 ;IF FAILED, NOTIFY HIM
MOVE T2,TODCLK ;GET CLOCK
MOVEM T2,HSHTIM(Q1) ;STAMP IT
SETZRO HSHWVT,(Q1) ;NOT VOTING ANY MORE
INCR HSHCNT,(Q1) ;SEIZE IT
SETZM T1 ;NEED THIS BLOCK
CALLRET CFSRSK ;AND RETURN GOOD
;HERE IF VOTE FAILED.
;If retry specified, leave the vote packet in the hash table, with
;HSHWVT and HSHYES set. This is done for two reasons:
; 1. So that the resource freed message can find it and
; wake up the waiting fork
; 2. So that other requestors can detect that a vote
; has failed so that they will not start their own
; vote. Although this is not strictly necessary,
; it does minimize overhead in the monitor and on the CI.
;Note that leaving HSHWVT and HSHYES set will cause the vote processor
;to allow accesses to this resource since we have already been told "no".
;If "no retry", unlink the packet and release it. Return the reason for
;the failed vote (found in HSHDRC) in T2.
CFSGT3: MOVE T1,Q1 ;Copy pointer
SKIPE RTYFLG ;[8960] Shall we try, try again?
IFSKP. ;[8960] If not
LOAD Q1,HSHDRC,(T1) ;Get the reason for the NO
CALL HSHULN ;Unlink it
CALL @HSHRET(T1) ;release it
MOVE T2,Q1 ;Move reason code to T2
CALLRET CFSFAL ;AND DONE
ENDIF.
SETZM T1
JRST CFSGTX ;FAIL
ENDSV.
;Common routine to routine good
CFSRSK: CFSULK
RETSKP ;AND DONE
SUBTTL Resource manager -- CFSRMV (Remove entry from hash table)
;ROUTINE TO REMOVE AN ENTRY FROM THE HASH TABLE
; T1/ ENTRY
;CFSRMV just removes the entry
;CFSRMX also posts removal
;RETURNS: +1 always
; If CFSRMX is called:
; T1/ 0 if resource unconditionally available
; T2= 0 =) not removed even though available
; -1 if resource being released but not yet available.
; In this case, the resource has not been released.
;Must be called with CFS interlock
CFSRMX: TDZA T2,T2 ;REMEMBER TO POST
CFSRMV: SETOM T2 ;DON'T POST
SKIPLE HSHPST(T1) ;[7247] Want posting?
SKIPE T2 ;YES. SHOULD WE HONOR IT?
IFSKP.
INCR HSHCNT,(T1) ;MARK IN USE FOR NOW
CALL @HSHPST(T1) ;DO POST
IFSKP.
JUMPE T1,RETO ;If delay release, say so.
SETZRO <HSHCNT,HSHTYP>,(T1) ; Clean these up
SETZM T2 ;Say it is still in the table though
CALLRET RETZ ;And done
ENDIF.
ENDIF.
TMNE HSHTAM,(T1) ;[7247] Is this a cached block?
SOS CFACCT ;[7247] Yes, decrement currently cached count
CALL HSHULN ;Unlink it
CALL @HSHRET(T1) ;FREE THE BLOCK
MOVEI T2,1 ;Removed.
CALLRET RETZ
;Companion routine to unlink an entry from the hash table
; T1/ pointer to entry to remove
;Returns: +1 always
; preserves T1
HSHULN: MOVE T2,HSHLNK(T1) ;Get forward pointer
MOVE T3,HSHBKP(T1) ;Get back pointer
MOVEM T2,HSHLNK(T3) ;Link previous to next
SKIPE T2 ;Was there a next?
MOVEM T3,HSHBKP(T2) ;Yes. Give it a new previous pointer
RET ;And done
SUBTTL Resource manager -- CFSNDO (Undeclare a resource)
;Routine to undeclare a resource.
; T1/ ROOT CODE
; T2/ QAULIFIER
;Returns:
; +1 /couldn't
; +2 done
CFSNDS: TDZA T3,T3 ;Make fairness test
CFSNDO::SETOM T3 ;No count
ASUBR<AC1,AC2,AC3>
CFSLOK
CALL HSHLOK ;LOOK IT UP
JRST [CALLRET CFSFAL]
LOAD T3,HSHCNT,(T1)
SOJL T3,[CALLRET CFSFAL]
STOR T3,HSHCNT,(T1) ;NEW COUNT
JUMPG T3,[CALLRET CFSRSK] ;IF STILL OWNED, GO ON
;RESOURCE NOW UNDECLARED. SEE IF ANYONE WAITING
SAVEQ ;SOME WORK REGS
TMNN HSHLOS,(T1) ;LONG BLOCK?
JRST CFSND3 ;IF NOT, MOVE ON
MOVE Q1,T1 ;BLOCK
ADDI Q1,HSHBTT ;GET TO THE BIT TABLE
MOVSI Q2,-<NFKS+^D35>/^D36 ;WORDS IN BIT TABLE
;Loop over bit table looking for a fork to wake up
CFSND1: SKIPN T2,0(Q1) ;ANYTHING HERE?
JRST CFSND2 ;NOPE
JFFO T2,.+1 ;GET BIT NUMBER
MOVE T2,BITS(T3) ;GET BIT NUMBER
ANDCAM T2,0(Q1) ;TURN IT OFF
MOVEI T1,0(Q2) ;GET WORD NUMBER
IMULI T1,^D36
ADDI T1,0(T3) ;FORK NUMBER
CALL UNBLKF ;UNBLOCK IT
CALLRET CFSRSK ;AND DONE
CFSND2: ADDI Q1,1 ;NEXT BIT TABLE WORD
AOBJN Q2,CFSND1 ;DO NEXT WORD
; ..
;Here if no local fork waiting. See if another host is waiting
CFSND3: SKIPN T3,HSHNBT(T1) ;[8960] Anything here?
IFSKP. ;[8960] If so
SKIPE AC3 ;[8960] User want to leave a record of this?
IFSKP. ;[8960] Yes
SETONE HSHRFF,(T1) ;So do it
ENDIF.
CALL CFNOHS ;Tell them
ENDIF.
CALLRET CFSRSK ;And done
SUBTTL Resource manager -- CFSOHS (Notify rejected hosts after undeclare)
;Routine to notify other hosts who were rejected for a resource.
;This is called whenever a resource is undeclared and one or more
;bits is set in HSHNBT
; T1/ hash packet
;Returns: +1 always
; call with interlock set, please
CFNOHS: SAVEAC <P1> ;Where to save packet
IFN CFSSCA,< ;Only if SCA
MOVEM P,CFSSVP ;Save incoming stack
MOVE P,CFSSTK ;Get local stack
MOVE P1,T1
DO.
SKIPN T3,HSHNBT(P1) ;Any body here?
EXIT.
CALL GVOTE1 ;GET A VOTE BUFFER
EXIT.
JFFO T3,.+1 ;GET HOST NUMBER WAITING
MOVE T3,BITS(T4) ;GET THE CORRESPONDING BIT
ANDCAM T3,HSHNBT(P1) ;TURN IT OFF
MOVEI T3,.CFRFR
STOR T3,CFCOD,(T1) ;CODE
DMOVE T2,HSHROT(P1) ;GET RESOURCE
DMOVEM T2,CFROT(T1) ;STASH IT
MOVE T2,T4 ;HOST NUMBER
CALL SCASND ;(T1,T2/T3)
IFSKP. ;[8960] If it worked
LOOP. ;[8960] Loop for the next one
ENDIF. ;[8960] Otherwise it failed
PIOFF
CALL CFSWDN ;Return the buffer
PION
LOOP.
ENDDO.
MOVE P,CFSSVP ;Restore original stack
> ;IFN CFSSCA
RET ;And done
;Pseudo routine to return failure.
CFSFAL::CFSULK
RETBAD() ;COULDN'T
SUBTTL Resource manager -- CFSUGD (Upgrade or downgrade a resource lock)
;Routine to upgrade (or downgrade) a resource lock.
; T1/ root code
; T2/ qualifier
; T3/ force voting,,new access
; Call with CFS interlock set!
;Returns (interlock cleared)
; +1 not currently held, or can't upgrade
; T2=-1 An error occurred in which this system could not
; find the resource to upgrade or a vote was in
; progress on this resource and we can't upgrade.
; T2>0 This system attempted to upgrade the access of the
; resource by voting for the new access. This vote
; request failed. The first reason we were told NO
; (found in HSHDRC) is returned.
;
; +2 did it. Share count incremented
;This routine is used to "seize" a resource without requiring
;the deallocation of resources. The intended use is for file
;access resources that are either "shared", "exclusive" or
;"unowned".
CFSUGZ: SETO T4, ;Force all votes
JRST CFSUG2 ;And enter
CFSUGA::TDZA T4,T4 ;Force vote
CFSUGD::MOVEI T4,1
CFSUG2: SAVEQ
DMOVE Q2,T3 ;Save incoming args
CALL HSHLOK ;LOOK UP THE REQUEST
JRST CFSUGF ;Can't find the resource!
;FOUND IT.
JN <HSHWVT>,(T1),CFSUGF ;A vote is pending on this resource - fail
INCR HSHCNT,(T1) ;Freeze it here
MOVE Q1,T1 ;COPY POINTER
JUMPL Q3,CFSUG1 ;If all force, go to it
OPSTR <CAME Q2,>,HSHTYP,(T1) ;ALREADY AT THIS TYPE?
JRST CFSUG0 ;NO
CALLRET CFSRSK ;YES, SUCCESS
;Not at this level
CFSUG0: LOAD T2,HSHTYP,(Q1) ;GET TYPE OF CURRENT RESOURCE
CAIE T2,.HTOEX ;ARE WE THE ONLY OWNER?
JRST CFSUG1 ;NO
STOR Q2,HSHTYP,(Q1) ;Stash new access
CALLRET CFSRSK ;And succeed
;HERE IF WE MAY NOT BE THE ONLY OWNER. FREEZE CURRENT RESOURCE AND
;TRY TO GET EXCLUSIVE ACCESS FOR THE CHANGE
CFSUG1: SETONE HSHUGD,(Q1) ;NOTE UPGRADE VOTE
IFLE. Q3 ;If forcing
SETONE HSHAVT,(Q1) ;Say to force
ENDIF.
MOVE T1,Q2 ;Copy desired type for VOTEr
CALL VOTEWS ;DO IT.
SETZRO <HSHAVT,HSHUGD,HSHWVT>,(Q1) ;NOT WAITING ANYMORE
JN HSHYES,(Q1),[
TMNN HSHCNT,(Q1) ;Any count?
CALL CFNCNT ;No!
DECR HSHCNT,(Q1) ;If can't upgrade...
LOAD T2,HSHDRC,(Q1) ;...get reason for NO...
CALLRET CFSFAL] ;...and fail
STOR Q2,HSHTYP,(Q1) ;SET IT
CALLRET CFSRSK ;And succeed
CFSUGF: SETOM T2 ;We could not find the resource or
CALLRET CFSFAL ;...vote in progress on it. Fail - no reason.
SUBTTL The voter -- VOTEW (Start vote and wait for results)
;ROUTINE TO START VOTE AND WAIT FOR RESULTS.
; T1/ TYPE WE ARE VOTING ON
; Q1/ REQUEST TO VOTE ON
;Returns +1 always. Result of vote indicated by HSHYES(Q1)
;
;This routine sends out requests to all other CFS processors and waits for the
;tallies. Tallies are processed as in-coming CFS requests and are therefore
;handled by the scheduler.
;
;VOTEW does a "regular vote".
;VOTEWS does a "seize" vote
VOTEWS: TDZA T2,T2 ;REMEMBER SEIZE
VOTEW: MOVEI T2,1 ;REMEMBER REGULAR VOTE
IFN CFSSCA,< ;if SCA is present
SAVEP5 ;Work regs
MOVE P2,T2 ;Save type
SETONE HSHWVT,(Q1) ;MARK VOTING
; SETZRO HSHODA,(Q1) ;No optional data yet
STOR T1,HSHVTP,(Q1) ;Store vote type
NOSKED
CFSULK
;Here to restart voting
VOTRST: SKIPN CFSCMC ;Any connects outstanding?
IFSKP. ;If so
MOVEI T1,DISET ;Wait for equal
HRLI T1,CFSCMC ; of this work
CALL CFSWUP ;Do it
ENDIF.
DO.
SKIPN T1,DLYLOK ;[8960] A delay in effect?
IFSKP. ;[8960] If so
SUB T1,TODCLK ;Get relative time
IFG. T1 ;If we still need to wait...
CALL SETBKT ;Compute wait time
HRRI T1,CFRCNW ;Wait
CALL CFSWUP ;Do it
MOVE T1,TODCLK ;Get now
CAMGE T1,DLYLOK ;Really time to wake up?
LOOP. ;No
ENDIF.
SETZM DLYLOK ;Yes
CALL CLRDLY
ENDIF.
ENDDO.
MOVEM P,CFSSVP ;Save stack pointer
MOVE P,CFSSTK ;Get new stack
AOS T1,VOTNUM ;GET A VOTE DIALOGUE
STOR T1,HSHUNQ,(Q1) ;Set this now
SETZRO <HSHVRS,HSHYES>,(Q1) ;ASSUME NO NO'S
SETZRO HSHRTY,(Q1) ;And now resends yet either
SETZRO HSHDLY,(Q1) ;No delays yet either
SKIPE P3,CFSHCT ;[8960] Get host count of other hosts
IFSKP. ;[8960] If nobody out there...
MOVE P,CFSSVP ;Restore original stack
CFSLOK ;Lock up the data base
OKSKED ;Turn on scheduling
RET ;And return now
ENDIF.
SETZRO HSHVCT,(Q1) ;VOTE IS AT ZERO
SETZRO HSHDRC,(Q1) ;No denial reason code yet
SETZM HSHWTM(Q1) ;No wait time yet
SETZM P1 ;Nothing done yet
MOVSI P4,-HSTSIZ ;Loop over entire data base
; ..
;TOP OF VOTING LOOP. FOR EACH OTHER CFS PROCESSOR, SEND REQUEST.
;THE VOTING BUFFERS ARE PRELLOCATED AT SYSTEM START-UP. VOTE
;BUFFERS ARE ALLOCATED DIRECTLY FROM THE QUEUE AND ARE RETURNED
;TO THE QUEUE BY SCA. IF THE QUEUE IS EXHAUSTED, THE VOTE
;WILL BE DELAYED UNTIL SOME ARE FREED (NOT EXPECTED TO BE LONG)
VOTE1: TMNN HSHYES,(Q1) ;[8960] Already vetoed?
IFSKP. ;[8960] Yes
MOVE P,CFSSVP ;Restore stack
CFSLOK ;Yes
OKSKED
RET
ENDIF.
SKIPLE CFSHST(P4) ;THIS HOST UP?
SKIPL P5,CFHSTS(P4) ;maybe. CTS?
JRST VOTEW0 ;NO
TRNE P5,-1 ;Is this a "reduced" CFS?
IFSKP. ;If so.
TMNE HSHAVT,(Q1) ;Vote anyway?
ANSKP. ;If not
INCR HSHVCT,(Q1) ;Say it approved
AOJA P1,VOTEW0 ;Account for it and go on
ENDIF.
CALL GVOTE ;GET A VOTE BUFFER
NOP
; ..
; ..
;BUILD VOTE REQUEST IN THIS BUFFER. IT WILL BE SENT TO HOST (P4)
;A vote message is as follows:
; word 0= vote opcode,,vote dialogue
; word 1= root code
; word 2= qualifier
; word 3= access required
LOAD T2,HSHUNQ,(Q1) ;Get code
STOR T2,CFUNQ,(T1) ;STORE VOTING NUMBER
MOVEI T2,.CFVOT ;WE ARE VOTING
; SKIPN P2 ;VOTING OR SEIZING?
; MOVEI T2,.CFCEZ ;SEIZE IT
STOR T2,CFCOD,(T1) ;STORE IT
DMOVE T2,HSHROT(Q1) ;GET ROOT AND QUALIFIER
DMOVEM T2,CFROT(T1) ;STORE IT IN VOTER
LOAD T2,HSHVTP,(Q1) ;GET REQUEST TYPE
TRNN P5,-1 ;Full vote?
MOVEI T2,.HTOEX ;No. Must always be exclusive for these
MOVEM T2,CFTYP(T1)
HRRZ T2,P4 ;HOST NUMBER
TMNN HSVUC,(Q1) ;[8960] Vote to include HSHCOD?
IFSKP. ;[8960] If so
SETONE CFVUC,(T1) ;Set it
MOVE T3,HSHCOD(Q1) ;Get the code
MOVEM T3,CFDAT(T1) ;Send it off
ENDIF.
CALL SCASND
IFNSK. ;If failed
PIOFF
CALL CFSWDN ;Enqueue the buffer
PION
MOVE P,CFSSVP ;Restore stack
JRST VOTRST ;Do it again
ENDIF.
ADDI P1,1 ;Did one
VOTEW0: CAIGE P1,0(P3) ;Found them all yet?
AOBJN P4,VOTE1 ;DO THEM ALL!
MOVE P,CFSSVP ;Restore stack
; ..
;VOTES ALL SENT OFF. WAIT FOR ALL REPLIES
CAIGE P1,0(P3) ;Found all of them (or more)?
JRST VOTRST ;No. Start over
CALL UPDTCK ;UPDATE TOD CLOCK
DO.
TMNE HSHVRS,(Q1) ;NEED TO RESTART?
JRST VOTRST ;yes
TMNN HSHYES,(Q1) ;[8960] Someone veto the request?
IFSKP. ;[8960] If so...
CFSLOK
OKSKED
RET
ENDIF.
LOAD T2,HSHVCT,(Q1) ;GET COUNT OF RETURNS
CAIN T2,0(P3) ;NO. ALL IN?
EXIT. ;YES.
REPEAT 0,< ;Don't do stall
CALL GETMST ;GET CURRENT TIME
SUB T1,TODCLK ;COMPUTE TIME IN THE LOOP
CAIGE T1,MAXVWT ;WAITED TOO LONG?
LOOP. ;NO
> ;Repeat 0
;Here when we have waited a long time for the votes. Dismiss and
;try again later.
MOVE T2,Q1 ;Block address
MOVEI T1,VOTSWT ;WAIT ROUTINE
CSKED ;Be critical for the rest of this
OKSKED
CALL CFSWUP ;WAIT FOR IT
NOSKED
ECSKED
LOOP.
ENDDO.
; ..
;Votes are all in, and no nay-sayers
TMNE HSHDLY,(Q1) ;[8960]
IFSKP. ;[8960]
CFSLOK
OKSKED
RET
ENDIF.
;At least one respondent wants time to release the resource. Wait
MOVE T1,TODCLK ;Get now
ADDI T1,^D5000 ;When to retry
;The retry time is simply a precaution
;against the other node being low on resources.
MOVEM T1,HSHTIM(Q1)
MOVE T2,Q1 ;Packet address
MOVEI T1,VOTDWT ;WAIT ROUTINE
SETONE HSHDWT,(Q1) ;Note this
CSKED ;Be critical for the rest of this
OKSKED
CALL CFSWUP ;WAIT FOR IT
SETZRO HSHDWT,(Q1)
TMNE HSHVRS,(Q1) ;[8960] Restart or success?
IFSKP. ;[8960]
CFSLOK
ECSKED
RET
ENDIF.
NOSKED
ECSKED
JRST VOTRST ;DO IT AGAIN
;Scheduler tests for above.
VOTDWT: LOAD T1,FKST2,(Q3)
TMNE HSHVRS,(T1)
JRST 1(4) ;Awake to retry
TMNN HSHDLY,(T1)
JRST 1(4)
REPEAT 1,<JRST 0(4)>
REPEAT 0,<
MOVE T2,HSHTIM(T1) ;Time to retry?
CAML T2,TODCLK ;Still want to wait?
JRST 0(4) ;Yes
SETONE HSHVRS,(T1) ;No. restart the vote
JRST 1(4)
> ;REPEAT 0
VOTSWT: LOAD T1,FKST2,(Q3)
TMNE HSHVRS,(T1) ;NEED TO RESTART?
JRST 1(4) ;YES. AWAKE THEN
LOAD T2,HSHVCT,(T1) ;GET COUNT OF VOTERS
TMNN HSHYES,(T1) ;NO IN YET?
CAMN T2,CFSHCT ; NO. ALL VOTED IN?
JRST 1(4) ;YES.
JRST 0(4) ;NO
CFRCNW::SKIPG DLYLOK ;[7.1072] Still in delay?
JRST 1(4) ;No. Awake now
JRST BLOCKT ;Yes. Check on time
SUBTTL The voter -- GVOTE (Get a vote buffer)
;Routine to get a vote buffer
; Returns +1 on failure
; +2 success
GVOTE1::TDZA T1,T1 ;NO WAIT
GVOTE:: SETOM T1 ;WAIT
ASUBR <WFLAG>
DO.
PIOFF
SKIPE T1,VOTQ ;[8960] Get one
IFSKP. ;[8960] If none there
PION
SKIPN WFLAG
RETBAD() ;IF NO WAIT, ALL DONE
MOVEI T1,VBWAIT
CALL CFSWUP ;WAIT FOR SOME
LOOP.
ENDIF.
ENDDO.
MOVE T2,(T1)
MOVEM T2,VOTQ ;DEQUEUE THIS ONE
PION
SETZM SCALEN(T1) ;Clear the first word
RETSKP ;AND DONE
;SCHEDULER TEST TO WAIT FOR VOTE BUFFERS
VBWAIT: SKIPE VOTQ ;ANY HERE?
JRST 1(4) ;YEP
JRST 0(4) ;NOPE
> ;IFN CFSSCA
IFE CFSSCA,< ;If no SCA
RET ;No vote
> ;IFE CFSSCA
SUBTTL Periodic check -- CFSCHK (Scheduler poller)
;Scheduler poller
;Must either be INSKED or NOSKED
CFSCHK::SKIPE SCAILK ;OK to do this now?
RET ;No. Try again next time
SKIPN SCAFL1 ;[8960] Is KLIPA off-line?
IFSKP. ;[8960] If so
SETZ T1,0 ;either path
CALL CIONLT ;is it sound yet?
IFSKP. ;[8960] If yes
CALL PRTONL ;[8960] Set dual-port access
ELSE. ;[8960] If not
MOVX T1,^D1000 ;[8960] Come back in a sec
MOVEM T1,CFSTIM ;[8960] To check it again
ENDIF. ;[8960]
ELSE.
MOVX T1,^D5000 ;Back in five seconds, please
MOVEM T1,CFSTIM ;Store it
ENDIF.
SOSLE CFSTTM ;Time for full test?
RET ;No
MOVX T1,TIMSE0 ;Ten minutes from now
MOVEM T1,CFSTTM ;Set it
;CALLRET CFSCH1 ;Do a pass
;Worker routine to do the scheduler background tasks.
CFSCH1: AOS SCAILK ;Interlock it to prevent out-of-order messages
MOVEM P,CFSSVP ;Save incoming stack
MOVE P,CFSSTK ;Get a BETTER stack
CALL SCAPOL ;Check on the message spooler
MOVE P,CFSSVP ;Recover original stack
PIOFF ;Prevent races
TMNN SCWKP ;Anything here?
SKIPE SCAQ ;Anything here now?
CALL SKDRUN ;Yes, come back soon
SETZM SCAILK ;And release the interlock
PION ;Allow interruptions again
REPEAT 0,<
SOSLE PRGCNT ;time to scan hash table?
RET ;No
MOVEI T1,^D600 ;Do again in one minute
MOVEM T1,PRGCNT
CALLRET CFSRSE ;And do it
> ;REPEAT 0
RET
;Routine to make the scheduler stuff run ASAP
SKDRUN: SETZM CFSTIM ;Make next 100ms tick come to us
SETZM CFSTTM ;And make sure we do all of our stuff
RET
SUBTTL Periodic check -- SCAPOL (Process incoming SCA messages)
;SCAPOL - routine to process incoming SCA messages
;Called periodically either by unlocking the CFS interlock or by the scheduler.
;Scheduler calls are intended for processing requeued requests.
;No arguments.
SCAPOL::SAVEQ ;GET SOME WORK REGS
IFN CFSSCA,< ;Do we have SCA?
SETZM Q2 ;NO REQUEUE NODE YET
TMNN SCRSV ;RESTART VOTE QUEUED?
IFSKP.
SETZRO SCRSV ;YEP
CALL CFSRSV ;DO RESTART
ENDIF.
TMNN SCDDP ;Need DDMP to run?
IFSKP.
SETZRO SCDDP ;All done with this
AOS DDCFSF ;yes.
ENDIF.
TMNN SCDIS ;A pending disconnect?
IFSKP. ;If so
SETZRO SCDIS ;Clear it
PIOFF
MOVSI Q1,-HSTSIZ ;Scan hosts
DO.
SKIPLE T1,CFHSTS(Q1) ;This one active?
SKIPG CFHSTS(Q1) ;Yes. Is it pending for disconnect?
IFSKP.
SETZM CFSHST(Q1) ;Yes
SETZM CFHSTS(Q1) ;Yepper
ENDIF.
AOBJN Q1,TOP. ;Do them all
ENDDO.
PION
ENDIF.
SKIPN SCAQ ;Anything to do?
RET ;No.
SAVET ;Yes. Save regs
DO.
SKIPN Q1,SCAQ ;ANY STUFF HERE?
RET
CAMN Q1,Q2 ;IS THIS THE END?
RET ;YES. DON'T SCAN REQUEUED NODES
PIOFF
MOVE T2,0(Q1) ;GET FORWARD LINK
MOVEM T2,SCAQ ;DEQUEUE IT
IFE. T2 ;IF EMPTY
XMOVEI T2,SCAQ
MOVEM T2,SCTAIL ;INIT TAIL WHEN EMPTY
ENDIF.
PION
MOVE T1,Q1 ;Get pointer to message
CALL SCMSG ;Do a message
IFNSK.
CALL SCAENQ ;ENQUEUE IT FOR RETRY
SKIPN Q2
MOVE Q2,Q1 ;COPY REQUEUED ADDRESS
ENDIF.
LOOP.
ENDDO.
> ;IFN CFSSCA
IFE CFSSCA,<RET> ;If not SCA interface, return now
SUBTTL Call from SCA
;Call-back routine from SCS. Here when something about a connection
;changes.
; T1/ code
; T2/ connection i.d.
; T3/ callback related data if used
; T4/ callback related data if used
IFN CFSSCA,<
CFSINT::CAILE T1,CFMSFX ;[7.1190] Known function?
IFSKP.
EXCH T1,T2 ;Connect ID in T1
CALL @CFFCTB(T2) ;DO IT
ENDIF.
RET ;AND DONE
;Function table for above
CFFCTB: IFIW!R ;.SSDGR - Datagram received
IFIW!SCAIN ;.SSMGR - Message received
IFIW!SCABRK ;.SSPBC - Port broke connection
IFIW!LSNUP ;.SSCTL - Connect to listen
IFIW!CFSCPS ;.SSCRA - Connect response available
IFIW!CFSWDN ;.SSMSC - Message/datagram send complete
IFIW!R ;.SSDDG - Datagram dropped
IFIW!R ;.SSLCL - Little credit left
IFIW!CFSNDU ;.SSNCO - Node came online
IFIW!CFSOKS ;.SSOSD - OK to send data
IFIW!SCABRK ;.SSRID - Remote initiated disconnect
IFIW!SCACRA ;.SSCIA - Credit is available
IFIW!R ;.SSDMA - DMA complete
CFMSFX==.-CFFCTB-1
SUBTTL Call from SCA -- Message Received -- SCAIN (Receive message from SCA)
;Interrupt level routine to receive an incoming SCA packet
; T1/ connect i.d.
; T3/ packet address
; T4/ return address
SCAIN: EXCH T1,T3 ;Swap CID and packet address
LOAD T3,SID,T3 ;GET HOST INDEX
AOS CFRECV(T3) ;Got one
AOS CFSRCV ;[7211] ADD TO TOTAL RECEIVED
MOVEM T3,.MHSCI(T1) ;STASH IT
MOVEM T4,.MHDCI(T1) ;Save buffer return address
IFN CLEQIN,< ;[7.1072] If cluster ENQ code present
LOAD T2,CFCOD,(T1) ;[7.1072] Get opcode
CAIE T2,.CFENQ ;[7.1072] Is this an ENQ packet?
IFSKP. ;[7.1072] Yes so bypass CFS lock
CALL SCMSG ;[7.1072] (T1/) Process message and requeue buffer
NOP ;[7.1072] Never returns here!
RET ;[7.1072] Done
ENDIF. ;[7.1072]
> ;[7.1072]
SKIPN SCAILK ;Need to enqueue?
SKIPE SCAQ ;?
IFSKP. ;If not
CALL SCMSG ;Do a message now
SKIPA ;Need to enqeue it
RET ;And done
ENDIF.
CALLRET SCAENQ ;ENQUEUE IT NOW
SUBTTL Call from SCA -- Message Received -- SCMSG (Process a single received message)
;Routine to process a single received message
; T1/ pointer to the message
;Returns: +1 need to requeue. T1/ message pointer
; +2 success. Message already returned
SCMSG: SAVEAC <Q1>
MOVE Q1,T1
LOAD T2,CFCOD,(Q1) ;GET OPCODE
CAILE T2,.CFMAX ;KNOW HOW TO DO THIS?
JRST CFSFRE ;NO. FREE IT AND GO ON
CALL @[ IFIW!CFSRTV ;Vote
IFIW!CFSRVT ;Reply to vote
IFIW!CFSRFR ;Resource freeze
IFIW!CFSRTV ;Seize
IFIW!CFSOFC ;OFN change
IFIW!CFSEFC ;End of file
IFIW!CFTADA ;Time and date
IFE CLEQIN,< IFIW!CFCEAS]-1(T2);[7.1072] Shutdown
> ;[7.1072]
IFN CLEQIN,< IFIW!CFCEAS ;[7.1072] Shutdown
XADDR. (EQMSG)]-1(T2) ;[7.1072] ENQ message
> ;[7.1072]
IFNSK.
MOVE T1,Q1 ;Return pointer
RETBAD()
ENDIF.
JUMPE T1,RSKP ;If want to keep it, done
MOVE T1,Q1 ;Else, get address for return
CFSFRE: CALL SCARET ;RETURN SCA BUFFER
RETSKP ;And done
SUBTTL Call from SCA -- Message Received -- CFSRTV (Vote or seize)
;Vote processor. This code is called whenever a request to vote
;Arrives:
; Q1/ The request packet
;Called from the scheduler
;
;Uses:
; T1/ Resource block address
; T2/ Our current access to the resource
; T3/ The requested access in the vote packet
; P1/ Resource block address
; P2/ Delay time if failing
; P3/ Non-zero if want to release the resource
; P4/ Reason code for returning a NO to the vote
; Q2/ Reply type to the vote request
;
;Returns:
; +1 Please reqeue
; +2 done
CFSRTV: SAVEAC <P1,P2,P3,P4,Q2>
SETZB P3,P2 ;No data yet
SETZM P4 ;No reason for NO yet either
DMOVE T1,CFROT(Q1) ;GET CODES
CALL HSHLOK ;LOOK IT UP
IFNSK. ;If not here
SETZM P1 ;Indicate so
JRST CFSRV2 ;And OKAy it
ENDIF.
MOVE P1,T1 ;Save pointer
TMNN HSHTAM,(T1) ;[7247] Is this a cached block?
IFSKP. ;[7247] Yes
MOVE T1,HSHCOD(T1) ;[7247] Get the OFN
MOVX T2,OFNLAC ;[7247] Get bit indicating loss of access
IORM T2,SPTH(T1) ;[7247] Set it
AOS CFACUT ;[7247] Count this event
SETZM P1 ;[7247] Do not release block
JRST CFSRV2 ;[7247] Give an immediate YES answer
ENDIF. ;[7247]
MOVE T4,HSFLAG(T1) ;Get the flags
TXNN T4,HSHDWT ;Are we in a commit?
IFSKP. ;Yes, he loses
MOVX P4,.CDDWT ;Get reason code
JRST CFSRV3 ;He loses
ENDIF.
;Found the request. Look it over.
TMNN CFVUC,(Q1) ;[8960] Vote to include HSHCOD?
IFSKP. ;[8960] If so
MOVE T2,CFDAT(Q1) ;Get required value
CAMN T2,HSHCOD(T1) ;match?
ANSKP. ;They do not, he loses
MOVX P4,.CDVUC ;Get reason code
JRST CFSRV3 ;He loses
ENDIF.
LOAD T2,HSHTYP,(T1) ;Get our type
MOVE T3,CFTYP(Q1) ;Get his requested access
TXNN T4,HSHWVT ;Are we voting?
JRST CFSRT0 ;NO
;We are also voting on this. Decide which one can win
TXNN T4,HSHYES ;Did we lose already?
IFSKP. ;If so
TXNN T4,HSHUGD ;Upgrading?
JRST CFSRV2 ; No, he wins
JUMPE T2,CFSRV2 ;If we've only a place-holder, succeed
CAIE T2,.HTOEX ;Do we have it exclusively?
IFSKP. ;Yes, he loses
MOVX P4,.CDYUX ;Get reason code
JRST CFSRV3 ;He loses
ENDIF.
CAIN T2,0(T3) ;Do they agree?
JRST CFSRV2 ;Yes. Approve then
MOVX P4,.CDYUN ;No, get reason code
JRST CFSRV3 ;He loses
ENDIF.
JE HSHDLY,(T1),CFSTV1 ;If we do not have a commit, continue
MOVX P4,.CDVDL ;Otherwise, we have a commit. Get reason.
JRST CFSRV3 ;He loses
CFSTV1: LOAD T4,HSHVTP,(T1) ;Get our vote request
CAIE T3,.HTOEX ;He want exclusive?
CAIE T3,0(T4) ;No. Do they agree?
SKIPA T4,.MHSCI(Q1) ;No. One of us has to lose
JRST CFSRV2 ;Yes. Allow it then
MOVE T4,CFSHNM(T4) ;Get his serial number
CAMLE T4,MYPORT ;Is he the bigger wheel?
IFSKP. ;No, we are. He loses
MOVX P4,.CDVLN ;Get reason code
JRST CFSRV3 ;He loses
ENDIF.
SETONE HSHYES,(T1) ;Yes, he is bigger. We lose
JN HSHDRC,(T1),CFSTV2 ;If there is already a reason, don't destroy
MOVX T4,.CDVLN ;Get reason for our loss
STOR T4,HSHDRC,(T1) ;Store it
CFSTV2: TMNN HSHUGD,(T1) ;Are we upgrading?
JRST CFSRV2 ;No, he wins
JUMPE T2,CFSRV2 ;If a place-holder, he wins
MOVEI P2,^D50 ;If he loses, try again soon.
CAIE T3,.HTOEX ;He wants exclusive?
IFSKP. ;Yes, he loses too
MOVX P4,.CDVUX ;Get reason code
JRST CFSRV3 ;He loses
ENDIF.
CAIN T2,0(T3) ;No. Are they compatible?
JRST CFSRV2 ;Yes, he wins
MOVX P4,.CDVUN ;No, he loses. Get reason code
JRST CFSRV3 ;He loses
;We own this. See if he can share it
CFSRT0: IFE. T2 ;If this is a place-holder
JN HSHKPH,(T1),CFSRV2 ; And keeping, allow it directly
JRST CFSRV5 ;Else, try to remove it as a stale entry
ENDIF.
CAIE T3,.HTOEX ;Does he want exclusive
CAIN T2,.HTOEX ;DO WE OWN IT EXCLUSIVELY?
JRST CFSRT1 ;YES. CHECK IF WE CAN GIVE IT UP
;neither is exclusive. See if either is "promiscuous
CAIE T2,.HTOPM
CAIN T3,.HTOPM ;Do checks
JRST CFSRV2 ;Yes. allow it then
CAIE T2,0(T3) ;NO. SEE IF COMPATIBLE
JRST CFSRT1 ;CHECK IF WE CAN GIVE IT UP
JRST CFSRV2 ;OKAY IT
;Here if we aren't using it
CFSRT1: JE HSHCNT,(T1),CFSRT2 ;If not in use, continue
MOVX P4,.CDOCT ;It is in use. Get reason code.
JRST CFSRV3 ;He loses.
CFSRT2: SKIPE T2,HSHFCT(T1) ;Apply fairness?
CAMG T2,TODCLK ;OK to release it?
IFSKP. ;If not
SUB T2,TODCLK ;Compute difference
MOVE P2,T2 ;Data to send back (time to try again)
MOVX P4,.CDOFC ;Get reason code
JRST CFSRV3 ;Not okay
ENDIF.
;We can give it up. Here by falling through or from CFSRT0
CFSRV5: STOR T3,HSHVTP,(T1) ;Save requested access
MOVE T2,.MHSCI(Q1) ;GET I.D.
STOR T2,HSHRHN,(T1) ;STASH IN PACKET
LOAD T2,CFUNQ,(Q1) ;GET VOTE CODE
STOR T2,HSHVVL,(T1)
AOJA P3,CFSRV2 ;Approve and do release
REPEAT 0,<
CALL CFSRMX ;REMOVE ENTRY
SKIPE Q2,T1 ;Copy type, and test if available
IFSKP. ;If available
IFN. T2 ;And it was removed
MOVEI P1,0 ;No saved entry
ENDIF.
ENDIF.
JRST CFSRV4
> ;REPEAT 0
;At this point:
; P2/ Delay time if failing
; P3/ non-zero if want to release the resource
; P1/ resource address, if any
; Q1/ Request packet from other system
; P4/ Reason code for saying NO
; Q2 will be used to indicate reply type
; 0 -- OK
; 1 -- No
; -1 -- delayed yes
;Here to reply
CFSRV3: IFE. P2 ;Set bit only if not sending data
MOVE T2,.MHSCI(Q1) ;GET HOST NUMBER
MOVE T2,BITS(T2) ;GET BIT FOR THIS HOST
IORM T2,HSHNBT(T1) ;STORE INTO THE PACKET
ENDIF.
SKIPA Q2,[1] ;FAIL!
CFSRV2: MOVEI Q2,0 ;SUCCESS
CFSRV4: CALL GVOTE1 ;GET A BUFFER
RETBAD() ;FAILED. REQUEST A REQUEUE
IFE. Q2 ;If allowing it
SKIPN T2,P1 ;Any request here?
ANSKP. ;If so
SKIPE T3,HSHOKV(P1) ;Yes. Want to know about this?
CALL 0(T3) ;Yes. So tell someone (may change Q2)
IFG. P3 ;Want to try to release it?
EXCH T1,P1
;The following call may return -1 in T1, which changes a "yes" vote
;to "will be released, but not yet"
CALL CFSRMX ;(T1/T1,T2) And try to remove it
MOVE Q2,T1 ;Save type of release
MOVE T1,P1 ;Get back vote packet
ENDIF.
ENDIF.
IFG. Q2 ;If failing
SKIPG P2 ;And have someting to send
ANSKP.
MOVEM P2,CFDAT(T1) ;Stash it
SETONE CFODA,(T1) ;And say so
ENDIF.
MOVEI T2,.CFREP ;WE ARE REPLYING
STOR T2,CFCOD,(T1)
LOAD T2,CFUNQ,(Q1)
STOR T2,CFUNQ,(T1) ;COPY CODE
DMOVE T2,CFROT(Q1)
DMOVEM T2,CFROT(T1) ;MOVE LOCK ID
MOVEM Q2,CFTYP(T1) ;THE VOTE
STOR P4,CFDRC,(T1) ;Store the reason for saying NO, if any
MOVE T2,.MHSCI(Q1)
CALL SCASND ;SEND IT
IFNSK. ;[8960] Failed
PIOFF
CALL CFSWDN ;Return the buffer
PION
ENDIF.
MOVE T1,Q1 ;ENSURE NON-ZERO
RETSKP ;AND DONE
SUBTTL Call from SCA -- Message Received -- CFSRVT (Reply to vote)
;Routine to process returned vote.
; Q1/ packet
;Called from the scheduler or at PI level
CFSRVT: DMOVE T1,CFROT(Q1) ;GET VALUES
CALL HSHLOK ;LOOK IT UP
RETSKP
;Found a node
JE HSHWVT,(T1),RSKP ;IF NOT VOTING, DONE
LOAD T2,CFUNQ,(Q1) ;GET UNIQUE CODE
OPSTR <CAME T2,>,HSHUNQ,(T1) ;MATCH?
JRST RSKP ;NO. SKIP IT THEN
INCR HSHVCT,(T1) ;YES. ANOTHER COUNTY HEARD FROM
TMNN CFODA,(Q1) ;[8960] Providing optional data?
IFSKP. ;[8960] If so
DO.
SKIPG CFTYP(Q1) ;If a fail vote
IFSKP.
MOVE T2,CFDAT(Q1) ;Get the time stamp
MOVEM T2,HSHWTM(T1) ;Send it back
EXIT.
ENDIF.
SKIPN T2,HSHCDA(T1) ;[8960] Want to be notified?
IFSKP. ;[8960] If so
CALL 0(T2) ;Do so
EXIT. ;If +1, don't use it
ENDIF.
DMOVE T2,CFDAT(Q1) ;Get it
DMOVEM T2,HSHOPT(T1) ;Store it in the packet
SETONE HSHODA,(T1) ;Say we have some
ENDDO.
ENDIF.
AOS PSKD1 ;MAKE SURE THE SCHEDULER NOTICES THIS
MOVE T2,CFTYP(Q1)
JUMPE T2,RSKP ;IF OK, ALL DONE
IFL. T2 ;IF YES, BUT DELAY
MOVE T3,.MHSCI(Q1)
MOVE T3,BITS+^D18(T3)
LOAD T4,HSHDLY,(T1)
AOSE T2 ;OK WITH DELAY?
IFSKP.
IORM T3,T4 ;YES MARK IT
ELSE.
ANDCAM T3,T4 ;ELSE, UNMARK IT
DECR HSHVCT,(T1) ;Discount vote if this
ENDIF.
STOR T4,HSHDLY,(T1)
ELSE.
SETONE HSHYES,(T1) ;NAY. INDICATE SO
JN HSHDRC,(T1),RSKP ;If there is already a reason, don't destroy
LOAD T2,CFDRC,(Q1) ;Get reason for NO
STOR T2,HSHDRC,(T1) ;Store it
ENDIF.
RETSKP ;AND DONE
SUBTTL Call from SCA -- Message Received -- CFSRFR (Resource freed)
;Routine called when a resource is freed. If anyone is waiting, awake him.
;This routine is used to process an incoming message indicating
;that a resource is now free. The sending node provided this information
;because we requested this resource and were denied. We may or may
;not still require the resource.
;The sender sent this message from CFNOHS!
; T1/ Block address
CFSRFR: DMOVE T1,CFROT(Q1) ;GET RESOURCE ID
CALL HSHLOK ;LOOK IT UP
JRST RSKP
SETONE HSHRTY,(T1) ;AWAKE
AOS PSKD1 ;GET THE SCHEDULER AWAKE TOO
RETSKP ;AND DONE
SUBTTL Call from SCA -- Message Received -- CFSOFC (OFN change)
;Here when a "broadcast OFN change is received.
; Q1/ message block address
CFSOFC: DMOVE T1,CFROT(Q1) ;Get stuff
CALL HSHLOK ;Look it up
JRST RSKP ;Not known here
;found the block
MOVE T2,HSHCOD(T1) ;Get the OFN
TMNN HSHTAM,(T1) ;[7247] Is this a cached block?
IFSKP. ;[7247] Yes
MOVX T1,OFNLAC ;[7247] Get "lost access" bit
TDNN T1,SPTH(T2) ;[7247] It had better be set!
BUG.(HLT,CFSOAC,CFSSRV,SOFT,<CFSSRV - Invalid access to cached OFN>,,<
Cause: CFS has received a message from a remote system that an OFN has changed
and needs to be verified again. But CFS has found that the OFN is
cached and the OFNLAC bit is not set. This should not happen since
this bit should be set when the other system was granted access.
>) ;[7247] It's not!
RETSKP ;[7247] Ok, just return
ENDIF. ;[7247]
IFN DEBUG,< ;If debugging
MOVE T3,HSFLAG(T1) ;Get flags
TXNN T3,HSHTYP ;A place holder?
IFSKP. ;No.
TXNE T3,HSHWVT ;Better be voting then
TXNE T3,HSHUGD ;And not upgrading
ANNSK. ;If not both...
BUG.(HLT,CFSOFB,CFSSRV,SOFT,<CFSSRV - OFN owned at CFSOFC>,,<
Cause: CFS has received a message from a remote system that an OFN has changed
and needs to be verified again. But CFS has found that it owns the OFN.
It should never have received such a message.
>)
ENDIF.
> ;IFN DEBUG
JE SPTCDO,(T2),RSKP ;If not yet opened, ignore it
SETONE SPTSFD,(T2) ;Set "reverify" bit
RETSKP ;And done
SUBTTL Call from SCA -- Message Received -- CFSEFC (EOF received)
;Here when broadcast EOF is received.
; Q1/ Block address
CFSEFC: DMOVE T1,CFROT(Q1) ;Get IDs
CALL HSHLOK ;Look it up
JRST RSKP ;We odon't have this file
CALL CFADAR ;Decide if we should use it
JRST RSKP ;No
SETONE HSHODA,(T1) ;Yes.
DMOVE T2,CFDAT(Q1) ;Get it
DMOVEM T2,HSHOPT(T1) ;Copy it
RETSKP ;And done
SUBTTL Call from SCA -- Message Received -- CFTADA (Time and date arrived)
;Here when TAD arrives
CFTADA: MOVE T1,CFROT(Q1) ;Get it
MOVEM T1,CFTADL ;Store it for perusal
AOS JB0FLG ;Get it noticed
RETSKP ;And done
SUBTTL Call from SCA -- Message Received -- CFCEAS (Cease)
COMMENT *
When a system tells its users "System going down in ........" and the shutdown
time is less than one hour away, we check to see if we have any disks onlined
via the MSCP server. If so, we broadcast the shutdown time to the other
systems in the cluster; the same goes for "Shutdown canceled" and "Timesharing
is over". This allows the other systems to see if they have any structures
mounted via the MSCP server on the system which is doing the broadcasting. If
a system finds such mounted structures, it sends to OPR and the CTY a message
stating the remote system's shutdown status and a list of the structures
effected.
Routine CFCBRD is called from MEXEC's shutdown processing to do the broadcast.
Routine CFCEAS processes the incoming message by placing the data (node number,
shutdown time, and node name) in a resident free space block and linking it in
a chain of blocks pointed to by location CCHEAD.
CHKR finds the queued blocks and calls routine CHKCLC. The interlock between
the CHKR routine and the interrupt level code is an EXCH instruction on
location CCHEAD. The data is retrieved from the block, effected structures are
found, and QUEUE% is used to pass the information to OPRs and the CTY.
*
;CFCEAS - PROCESSES CEASE MESSAGE FROM A REMOTE SYSTEM
; Q1/ ADDRESS OF PACKET
; CALL CFCEAS ;(Q1/T1)
; RETURN +2
CFCEAS: SAVEP
DMOVE P1,CFDAT(Q1) ;Get node number and cease time
DMOVE P3,CFROT(Q1) ;Get both words of node name
MOVEI T1,CCLEN ;GET LENGTH OF CLUSTER CEASE INFO BLOCK
HRLI T1,.RESP1 ;PRIORITY 1
MOVE T2,[RS%SE0+.RESGP] ;FROM THE GENERAL POOL
CALL ASGRES ;(T1,T2/T1) GET THE SPACE
IFNSK.
BUG.(INF,CFCCML,CFSSRV,SOFT,<CFSSRV - Cluster cease message lost>,,<
Cause: Another system sent a "cluster cease" that could not be queued because
there was no available resident free space.
Action: If this becomes persistent, find out why there is no freespace
available. Run SYSDPY and use the RE display to see if the general
pool is being used. If there is no one particular freespace hog,
consider building your monitor with an increase in the freespace
general pool. If this problem is reproducible, set this BUGINF
dumpable and submit an SPR along with the dump and instructions on
reproducing the problem.
>,,<DB%NND>) ;[7.1210]
JRST CFCEAX ;TOO BAD, BUT NOT CRTITICAL
ENDIF.
SKIPE T2,CCHEAD ;GET HEAD OF QUEUED BLOCKS
IFSKP.
MOVEM T1,CCHEAD ;NONE THERE, MAKE THIS ONE FIRST
ELSE.
CFCEA1: SKIPN T3,CCNXT(T2) ;GET NEXT BLOCK
IFSKP.
MOVE T2,T3 ;WE HAVE ONE
JRST CFCEA1 ;KEEP GOING
ENDIF.
MOVEM T1,CCNXT(T2) ;ADD THIS ONE TO THE END
ENDIF.
DMOVEM P1,CCNOD(T1) ;PUT NODE NUMBER AND TIME IN BLOCK
DMOVEM P3,CCNAM1(T1) ;PUT NODE NAME IN BLOCK
CFCEAX: MOVE T1,Q1 ;INSURE T1 IS NON-ZERO SO BUFFER IS RETURNED
RETSKP
;CHKCLC - CALLED BY CHKR TO SEE IF THERE ARE ANY QUEUED CLUSTER CEASE BLOCKS
;WAITING TO BE PROCESSED
; CALL CHKCLC ;(/)
; RETURN +1
; LOCAL AC USE:
; Q1,Q2 - EXTEND
; Q3 - STRING TERMINATOR
; P1 - FREE SPACE BLOCK
; P2 - KDB
; P3 - UDB
; P4 - SIXBIT STRUCTURE NAME
; P5 - "WE FOUND AT LEAST ONE STRUCTURE" FLAG
SWAPCD
;[8863]
;Milestone - These values were increased because of ILMNRFs. The
;more structures you have served, the higher potential exists for
;ILMNRFs when this routine scribbles on the stack.
SLEN==^D20 ;[8863] Words to hold structure names
HLEN==^D30 ;[8863] Words to hold header text
CHKCLC::SETZ T1, ;THIS IS THE INTERLOCK
EXCH T1,CCHEAD ; WITH THE INTERRUPT LEVEL CODE
JUMPE T1,RTN ;IF NO QUEUED BLOCKS, QUIT
SAVEPQ
STKVAR <<SNAMS,SLEN>,<MSG,SLEN+HLEN>>
CHKCL4: SETZ P5, ;START WITH NO STRUCTURES FOUND
MOVE P1,T1 ;PRESERVE BLOCK ADDRESS
MOVE T1,CCNOD(P1) ;GET NODE NUMBER
MOVEI Q1,SNAMS ;MAKE BP
HRLI Q1,(<POINT 7,>) ; TO STRUCTURE NAME SPACE
MOVEI Q3," " ;LOAD "SPACE"
ADD T1,CHNTAB+7 ;GET NODE'S
MOVE P2,CDBUDB(T1) ; KDB
CHKCL1: SKIPN P3,KDBUDB(P2) ;GET NEXT UDB
JRST CHKCL2 ;DONE
MOVX T1,US.TPD ;THREE-PORTED
TDNE T1,UDBSTS(P3) ; HERE?
JRST CHKCL3 ;YES, THEN NO ONE IS USING IT
SKIPGE T1,UDBSTR(P3) ;NO, PART OF STRUCTURE?
JRST CHKCL3 ;NO, THEN IT'S NOT MOUNTED (NOT EVEN MOUNTR)
HLRZ T2,T1 ;YES, GET LOGICAL UNIT OF STRUCTURE
JUMPN T2,CHKCL3 ;IF NOT 0, MOVE ON (ONLY IDENTIFY IT ONCE!)
SETO P5, ;FOUND A STRUCTURE MOUNTED THROUGH A SERVER
HRRZ T1,UDBSTR(P3) ;GET STRUCTURE NUMBER
CALL GNAME ;(T1/T1) GET STRUCTURE NAME
MOVE P4,T1 ;PUT IT SOMEWHERE
MOVEI T1,6 ;GET MAX CHAR. COUNT OF STR NAME
MOVEI T2,P4 ;MAKE BP
HRLI T2,(<POINT 6,>) ; TO IT
SETZB T3,Q2 ;SINGLE WORD BYTE POINTERS
MOVE T4,T1 ;GET CHAR. COUNT AGAIN
EXTEND T1,[MOVSO 40] ;CREATE STR NAME IN ACSII
JFCL
IDPB Q3,Q1 ;PUT IN SPACE
CHKCL3: AOJA P2,CHKCL1 ;GO DO NEXT UDB
;...
;...
CHKCL2: SETZ Q3,
IDPB Q3,Q1 ;TIE OFF STRUCTURE NAMES
HRROI T1,MSG ;YES, GET BP TO MESSAGE
HRROI T2,[ASCIZ/
/]
SETZ T3,
SOUT ;WAKE UP THE OPERATOR
HRROI T2,CCNAM1(P1)
SOUT ;NODE NAME
SKIPG CCTIM(P1) ;CEASE SCHEDULED?
IFSKP.
;Cease scheduled
HRROI T2,[ASCIZ/ is going down at /]
SOUT
MOVE T2,CCTIM(P1) ;GET TIME
ODTIM ;PUT IT IN MESSAGE
HRROI T2,[ASCIZ/. /]
SOUT
HRROI T2,CHKMS1 ;ASSUME STRUCTURES FOUND
SKIPN P5 ;WERE THERE ANY?
HRROI T2,CHKMS2 ;NO, GET DIFFERENT MESSAGE
ELSE.
SKIPE CCTIM(P1) ;SHUTDOWN CANCELED?
IFSKP.
;Shutdown canceled
SKIPN P5 ;ANY STRUCTURES FOUND?
JRST CHKCL5 ;NO
HRROI T2,[ASCIZ/ has canceled its shutdown. It is no longer
necessary to dismount the following structures:
/]
ELSE.
;Timesharing is over
HRROI T2,[ASCIZ/ has ceased timesharing. /]
SOUT
HRROI T2,CHKMS1 ;ASSUME STRUCTURES FOUND
SKIPN P5 ;WERE THERE ANY?
HRROI T2,CHKMS2 ;NO, GET DIFFERENT MESSAGE
ENDIF.
ENDIF.
SOUT ;CREATE HEADER
SKIPN P5 ;ANY STRUCTURES FOUND?
IFSKP.
HRROI T2,SNAMS ;YES, GET BEGINNING OF STRUCTURE NAMES
SOUT ;MOVE THEM TO END OF MESSAGE
ENDIF.
;...
;...
MOVEI T2,MSG ;GET BEGINNING ADDR OF MESSAGE
MOVEI T3,.QBSYS ;TYPE IS "SYSTEM MESSAGE"
CALL WROPR0 ;(T1,T2,T3/) WRITE-TO-OPR
CHKCL5: MOVE P2,CCNXT(P1) ;GET NEXT QUEUED BLOCK
MOVE T1,P1 ;POSITION BLOCK ADDR
CALL RELRES ;(T1/) RELEASE THIS BLOCK
SKIPE T1,P2 ;IS THERE ANOTHER BLOCK?
JRST CHKCL4 ;YES
RET
ENDSV.
CHKMS1: ASCIZ/Before that system
is shutdown, this system should dismount the following
structures:
/
CHKMS2: ASCIZ/No structure
dismounting is needed on this system.
/
RESCD
SUBTTL Call from SCA -- SCABRK (Node went away)
;Here when a connection is broken for any reason
; T1/ connection i.d. or -1 for extra callback
SCABR0: AOS CFSSKC ;Make the scheduler do the check
ISB SCDCHN ;And make it notice
SCABRK: SKIPGE T3,T1 ;Is this an extraneous callback?
RET ;Yes, just return
LOAD T1,SID,T1 ;GET HOST INDEX
SKIPN CFSHST(T1) ;This node active in some way?
IFSKP.
SKIPL T2,CFHSTS(T1) ;If active, is it up (i.e. counted)?
IFSKP. ;If so...
SOS CFSHCT ;ONE LESS
TRNE T2,-1 ;A full or reduced?
SOS CFSHCM ;Full.
CALL MXCIND ;(/T2) Get the max number of nodes ever on CI
IMUL T2,DLYTIM ;Multiply by delay per node
ADD T2,NDSTTM ;Add allowable time for reloading the KLIPA
ADD T2,TODCLK ;Compute time the delay is over
IFN DEBUG,<
; SKIPE DLYFLG ;Doing delay stuff?
> ;IFN DEBUG
MOVEM T2,DLYLOK ;And lock voting for a bit
CALL PHYNOL ;Declare the disk's offline
MOVE T2,CFSHNM(T1) ;Get the serial number
CALL PUTOLD ;And install it now
SKIPE SCAILK ;OK TO DO THIS NOW?
IFSKP.
SETZM CFSHST(T1) ;Not in use now
CALL CFSRSV ;YES, RESTART VOTE
ELSE.
SETONE <SCRSV,SCDIS> ;NO. SAY WE NEED IT LATER
MOVX T2,1B0 ;Get the sign bit
ANDCAM T2,CFHSTS(T1) ;Mark this entry
ENDIF.
ELSE. ;If not counted
SOS CFSCMC ;One less connection being done
SETZM CFSHST(T1) ;And this one is no longer active
ENDIF.
PIOFF
DO. ;Return queued send buffers
SKIPN T3,CFSSMQ(T1) ;Anything here?
EXIT. ;No. All done
MOVE T2,0(T3) ;Get next
MOVEM T2,CFSSMQ(T1)
CALL CFSWDN ;Return the buffer
LOOP. ;Do them all
ENDDO.
PION
ENDIF.
RET
SUBTTL Call from SCA -- LSNUP (Connect to listen)
;Here when listen circuit has a sucker.
;Called at interrupt level or with CFS interlock set
; T1/ Connect I.D.
; T3/ Pointer to serial number
LSNUP: SAVEQ
LOAD Q1,SID,T1 ;GET HOST INDEX
MOVE T2,CFSHST(Q1) ;[7.1021] Get the listener type
CAME T2,[-2] ;[7.1021] Is this a dump listener?
IFSKP. ;[7.1021] Yes
AOS CLDWRD ;[7.1021] Enable cluster dump facility
RET ;[7.1021] Done, we will be crashing soon
ENDIF. ;[7.1021]
HRRZ T2,OPDTYP(T3) ;Get net number
;Here if we know about this. See if connector is trying to
;connect to us (or we know about it).
DMOVE Q2,OPDNAM(T3) ;Get its name
HLLZS Q3 ;Get rid of excess
LSH Q1,1 ;Get index
DMOVEM Q2,CFNNAM(Q1) ;Stash the name
LSH Q1,-1
MOVE Q2,T1 ;SAVE CID
MOVE T1,OPDSER(T3) ;GET SERIAL NUMBER
HLRE Q3,OPDTYP(T3) ;Get type of node
XOR T2,MYPOR1 ;Compare net numbers
TRNE T2,-1 ;Same?
SETZM Q3 ;No. Treat as a reduced node then
MOVEM T1,CFSHNM(Q1) ;AND PORT NUMBER HERE
MOVEI T3,HSTSIZ ;SIZE OF HOST TABLE
CAMLE T1,MYPORT ;[8960] Higher priority than I?
IFSKP. ;[8960]
DO.
SKIPLE CFSHST(T3) ;ACTIVE?
CAME T1,CFSHNM(T3) ;IS THIS ALREADY CONNECTED?
IFSKP.
SKIPL CFHSTS(T3) ;Make sure is fully active
ANSKP.
BLCAL. (SC.REJ,<CFSHST(Q1),[0]>)
NOP
SETZM CFSHST(Q1) ;THIS SLOT NOW AVAILABLE
JRST LSNUP1 ;GO START A NEW LISTENER
RET ;DONE
ENDIF.
SOJGE T3,TOP.
ENDDO.
ENDIF.
;Here if we should accept
MOVE T1,CFSHNM(Q1) ;Get the serial number
CALL CHKOL0 ;see if we know about this one yet
STOR T1,ONFLG,MYPOR3 ;Store old/new flag byte
HRRM Q3,CFHSTS(Q1) ;Remember the type
AOS CFSCMC ;Note we are doing this
BLCAL.(SC.ACC,<Q2,<.,MYPORT>,[BUFSCT],[0]>); ACCEPT THE OVERTURE
IFNSK.
MOVE T3,T1 ;Move error code
MOVE T1,Q2 ;Get connect ID
CALL SC.NOD ;(T1/T1,T2) Get node number
BUG.(HLT,CFACCF,CFSSRV,SOFT,<CFSSRV - SC.ACC failed>,<<T2,NODE>,<T1,CID>,<T3,ERR>>,<
Cause: The call to SC.ACC to accept a connection failed. This indicates a
possible problem with SCAMPI.
Data: NODE - Node Number
CID - Connect ID
ERR - Error returned by SC.ACC
>)
ENDIF.
MOVEM Q2,CFSHST(Q1) ;NOW STORE CID
;NOTE: CFSHCT is incremented during the CFSOKS call-back
LSNUP1: CALL CFSLSN ;GET A NEW LISTENER
NOP
RET ;AND DONE
SUBTTL Call from SCA -- Connect response available -- CFSCPS (Connect response available)
;Here on reply to connect request
; T1/ CID
; T3/ Reply code
; T4/ Pointer to serial number
;We tried to connect to another node, and now a response is available.
;If it has accepted, we may already have a connection open to it.
;If that is true, the open connection was initiated by the other node,
;and the following algorithm applies:
;If we have the lower serial number, close this one.
;If they have the lower serial number, close the existing one.
CFSCPS: SAVEAC<P1,P2>
LOAD T2,SID,T1 ;Get local ID
SKIPE CFSHST(T2) ;This waiting?
SKIPL CFSHNM(T2) ;?
RET ;No. Ignore it then
;Found the waiting entry. See if it was accepted
SOS CFSCMC ;No more of this
MOVEM T1,CFSHST(T2) ;Store CID
IFE. T3 ;If rejected
SETZM CFSHST(T2) ;We are no longer waiting
RET ;And done
ENDIF.
;It was accepted. Make sure we are not connect another way
DMOVE P1,OPDNAM(T4) ;get its name
HLLZS P2 ;Get rid of excess
LSH T2,1 ;Get to index
DMOVEM P1,CFNNAM(T2) ;Stash its name
LSH T2,-1
LOAD P2,ONFLG,OPDNEW(T4) ;Get old/new byte
HLRE P1,OPDTYP(T4) ;Get type of connector
HRRZ T3,OPDTYP(T4) ;Get network nubmer
XOR T3,MYPOR1 ;Compare with our number
TRNE T3,-1 ;Same as us?
SETZM P1 ;No. Treat it as "reduced"
MOVE T4,OPDSER(T4) ;Get other node's serial number
CALL CFSCPX ;(T4/)See if we need to disconnect
RET ;Disconnected our initiator. Quit now
;..
;Here when we want to let this connection proceed. We may have disconnected
;an old connection.
;..
SKIPE SCAFL1 ;OK to allow this?
CALL CFSDIE ;No.
MOVEM T4,CFSHNM(T2) ;OK to store this now
HRROM P1,CFHSTS(T2) ;Set status
SETZM CFSENT(T2)
SETZM CFRECV(T2)
XMOVEI T3,CFSSMQ(T2) ;Get head of send queue
MOVEM T3,CFSSQT(T2) ;Link tail to head
SETZM 0(T3) ;Clear head
MOVE T1,CFSHNM(T2) ;Get its serial number
SKIPE P2 ;If he thinks it is new
CAMG T1,MYPORT ;Or I'm a big wheel
IFSKP. ;If not
EXCH P2,T2 ;Save index, get OLD/NEW arg
CALL CHKOLD ;Check it we've been here before
IFSKP.
MOVE T1,CFSHST(P2) ;Get connect ID
CALL SC.NOD ;(T1/T1,T2) Get node number
BUG.(HLT,CFRECN,CFSSRV,SOFT,<CFSSRV - Illegal reconnect>,<<T2,NODE>,<T1,CID>>,<
Cause: The VC between this system and another has been continued illegally.
This BUGHLT only occurs in a cluster and will only occur on the system
with the lowest CPU serial number. It happens when a system joins the
cluster and that system has been away longer than the CFS vote delay
period. This time period is calculated to be
(DLYTIM*maximum_CI_node_seen)+NDSTTM. Currenty this is 5 seconds per
CI node plus 10 seconds grace period.
Action: This BUGHLT usually occurs when a system has been hung for a long
period of time on the CI or if someone has stopped and continued a
halted system in the cluster (using EDDT breakpoints or other methods).
If this problem is persistent, there is a good chance that one of the
systems in the cluster is having CI problems. Another step which could
be taken would be to increase the value in DLYTIM and see if this
provides enough time for the cluster to stablize.
Data: NODE - Number that has re-established a connection
CID - Connect ID
>)
ENDIF.
EXCH T2,P2 ;Swap index and OLD/NEW arg
ENDIF.
;...
;...
MOVE T1,CFSHNM(T2) ;recover serial number
CALL CHKDLY ;Check if we are whole again!
AOS CFSHCT ;Another node in the list
MOVE T1,T2 ;Pass local node number
CALL ONLINE ;Do a message
SETONE SCCNC
TRNE P1,-1 ;IS this reduced
AOS T3,CFSHCM ;[8960] One more full voter on-line
MOVEI T1,0(T2) ;Copy host index
CALL SNDTIM ;Send it the TAD
SKIPE SCAILK ;Data base locked?
IFSKP. ;If not
CALL CFSRSV ;Restart votes (called without the lock)
ELSE. ;If so
SETONE SCRSV ;Note we need to do this ASAP
CALL SKDRUN ;Make the scheduler run ASAP
ENDIF.
RET ;And done
SUBTTL Call from SCA -- Connect response available -- CFSCPX (Disconnect duplicate connection)
;CFSCPX - Disconnect if there's a duplicate connection to this node
;Accepts:
; T4/ serial number of the other node
; CALL CFSCPX
;Returns +1: disconnected our initiator (the one that caused this call)
; +2: OK to proceed with this connection
;Preserves the temporary AC's except T3.
;Note: this was written to fix a bug in CFSCPS. It is not general-purpose.
;Calling it from anywhere else might be a mistake
CFSCPX: MOVSI T3,-HSTSIZ ;Scan table for a match
SAVET
DO.
CAME T4,CFSHNM(T3) ;Here?
IFSKP. ;If so, we have a conflict. Must do away with one
SKIPE CFSHST(T3) ;Really in use?
SKIPL CFHSTS(T3) ;?
ANSKP. ; If so...
MOVEI T1,0(T2) ;Assume we will zap our connection
CAMG T4,MYPORT ;Will we?
MOVEI T1,0(T3) ;No zap other side's initiator
PUSH P,T1
BLCAL. (SC.DIS,<CFSHST(T1),[0]>)
NOP
POP P,T1
IFN DEBUG,<
CALL OFLINE ;(T1) REPORT THE DISCONNECTION
>
SETZM CFSHST(T1) ;Clear entry
SKIPL T3,CFHSTS(T1) ;Which connection did we kill?
RET ;Our initiator. Don't continue connecting, then.
;Here when we disconnected the other side's initiator (the old connection).
;Need to decrement the host count and let the current connection continue.
SOS CFSHCT ;Indicate one fewer connections
TRNE T3,-1 ;Full or reduced?
SOS CFSHCM ;It was full
RETSKP ;Let the caller proceed
ENDIF.
AOBJN T3,TOP. ;Scan them all
ENDDO.
RETSKP
SUBTTL Call from SCA -- CFSWDN (Write completed)
;Here to put a packet on the vote queue
; T3/ Buffer address
CFSWDN::
IFN CLEQIN,< ;[7.1072] If ENQ code present
LOAD CX,CFCOD,(T3) ;[7.1072] Get opcode
CAIE CX,.CFENQ ;[7.1072] Is this an ENQ packet?
IFSKP. ;[7.1072] Yes
SKIPN -C%BINV(T3) ;[7.1072] Is this the VRB?
IFSKP. ;[7.1072] No, this is a vote buffer
MOVE T1,T3 ;[7.1072] Position buffer address for call
CALL @-C%BINV(T1) ;[7.1072] (T1/)Return the buffer to SCA
ENDIF. ;[7.1072]
RET ;[7.1072] Done
ENDIF. ;[7.1072]
> ;[7.1072]
IFN DEBUG,< ;Only for debugging...
LOAD CX,CFGWD,(T3) ;Check if special word is here
CAME CX,[252525] ;Is it?
BUG.(HLT,CFGARD,CFSSRV,SOFT,<CFSSRV - Vote packet address is bad>,,<
Cause: A bad vote packet address has been given to CFSWDN. The guard word did
not contatin 252525.
>)
> ;IFN DEBUG
EXCH T3,VOTQ ;PUT IT ON TOP
MOVEM T3,@VOTQ ;AND QUEUE REST OF QUEUE TO IT
RET ;DONE
> ;IFN CFSSCA
IFE CFSSCA,< ;If not SCA
CFSWDN==R ;Null routine
> ;IFE CFSSCA
SUBTTL Call from SCA -- CFSNDU (Node up)
;Node up
; T1/ SBI
IFN CFSSCA,<
CFSNDU: SKIPE SCAFL1 ;Are ports off?
CALL DEDKLP ;Yes. We are in trouble
CALL CFSCTH ;Try to connect to it
NOP
RET ;And done
SUBTTL Call from SCA -- CFSOKS (Ok to send)
;Here when a listener is really ready to send
; T1/ CID
CFSOKS: SAVEQ
LOAD Q1,SID,T1 ;get ID
SKIPLE CFSHST(Q1) ;Do we agree?
SKIPGE CFHSTS(Q1) ;Still?
RET ;No
SOS CFSCMC ;Discount this now
;yes. we must do soemthing about this
;Check for a conflict
MOVSI T2,-HSTSIZ
MOVE T3,CFSHNM(Q1) ;Get name
DO.
CAME T3,CFSHNM(T2) ;This one match?
IFSKP. ;if so.
SKIPE CFSHST(T2) ;Make sure is active
SKIPL CFHSTS(T2) ;""
ANSKP.
MOVEI Q2,0(Q1) ;Assume we will close his
CAML T3,MYPORT ;Will we?
MOVEI Q2,0(T2) ;No. Close ours
BLCAL. (SC.DIS,<CFSHST(Q2),[0]>)
NOP
IFN DEBUG,<
MOVE T1,Q2 ;GET LOCAL NODE INDEX
CALL OFLINE ;(T1) REPORT THE DISCONNECTION
>
SETZM CFSHST(Q2)
SKIPL T3,CFHSTS(Q2) ;Was it me or him?
RET ;Me. All done then
SOS CFSHCT ;Him. One less active node
TRNE T3,-1 ;Full or reduced?
SOS CFSHCM ;Full
EXIT.
ENDIF. ;And proceed with the connection
AOBJN T2,TOP.
ENDDO.
SKIPE SCAFL1 ;OK to allow this?
CALL CFSDIE ;No.
XMOVEI T3,CFSSMQ(Q1) ;Get address of head
MOVEM T3,CFSSQT(Q1) ;Link head to tail
SETZM 0(T3) ;Clear head
AOS CFSHCT ;Another one active
MOVE T1,Q1 ;Pass local node number
CALL ONLINE
SETONE SCCNC
HRROS T3,CFHSTS(Q1) ;Mark it active
SETZM CFSENT(Q1)
SETZM CFRECV(Q1)
TRNE T3,-1 ;Full or reduced?
AOS T3,CFSHCM ;[8960] Full, one more full voter
MOVEI T1,0(Q1) ;Copy the index
CALL SNDTIM ;Send it TAD
SKIPE SCAILK ;Data base locked?
IFSKP. ;If not
CALL CFSRSV ;Restart votes (called without the lock)
ELSE. ;If so
SETONE SCRSV ;Note we need to do this ASAP
CALL SKDRUN ;Make the scheduler run
ENDIF.
RET ;And done
SUBTTL Call from SCA -- SCACRA (Credit available)
;Credit arrived.
; T1/ CID
SCACRA: LOAD T1,SID,T1 ;Get local port
SETONE STCRA,(T1) ;Say it arrived
CALLRET SSENDQ ;Process the queue
SUBTTL Sending Messages -- SCAENQ (Enqueue a SCA message)
;ROUTINE TO ENQUEUE AN SCA MESSAGE
; T1/ MESSAGE TO ENQUEUE
;RETURNS:
; +1 ALWAYS
SCAENQ: PIOFF
MOVEM T1,@SCTAIL ;LINK INTO QUEUE
MOVEM T1,SCTAIL
SETZM 0(T1) ;NO FORWARD LINK
PION
RET ;DONE
> ;IFN CFSSCA
SUBTTL Sending Messages -- SCASND (Send a message)
;Routine to send a message.
; T1/ Buffer address
; T2/ host number
;Returns: +1/ failed. T3/ buffer address
; +2 success
IFE CFSSCA,<
SCASND::BUG.(HLT,CFSSMC,CFSSRV,SOFT,<CFSSRV - Tried to send a message>,,<
Cause: CFSSRV tried to send an SCA message and that option is not supported in
this version of TOPS-20.
>)
> ;IFE CFSSCA
IFN CFSSCA,<
SCASND::ASUBR <SCBUFF,SCHOST>
SKIPE CFSHST(T2) ;Is this on-line?
SKIPL CFHSTS(T2) ;And up?
IFNSK. ;If not
MOVE T3,T1 ;Return message buffer in T3
RETBAD() ;And tell caller
ENDIF.
PIOFF
SKIPN CFSSMQ(T2) ;[8960] A queue?
IFSKP. ;[8960] If so
CALL SENDQ ;Queue it up
PION
RETSKP ;And done
ENDIF.
AOS CFSENT(T2) ;Sent one
AOS CFSSND ;[7211] ADD TO TOTAL SENT
PION
DO.
SETZRO STCRA,(T2) ;Say we are about to send
BLCAL. (SC.SMG,<CFSHST(T2),[F.RTB+F.SPM],[VOTSZB],T1,[CFSPRI],[0],[0]>)
IFNSK. ;[8960] If failure
CAIE T1,SCSNEC ;[8960] Not enough credit?
IFSKP. ;[8960] If so...
MOVE T1,SCBUFF ;YES.
MOVE T2,SCHOST ;RESTORE ARGS
PIOFF ;[8960] Turn off PI system
TMNN STCRA,(T2) ;[8960] Credit arrive while we weren't looking?
IFSKP. ;[8960] If so
PION ;[8960] Turn PI back on
LOOP. ;[8960] and call SC.SMG again
ENDIF. ;[8960]
CALL SENDQ ;Queue it up
PION ;[8960] Turn PI back on and continue
ELSE. ;[8960] Not little credit left, error
MOVE T3,SCBUFF ;Return buffer address in T3
RETBAD() ;Didn't send it
ENDIF.
ENDIF. ;[8960] End of SMG failure code
ENDDO.
RETSKP ;AND DONE
ENDAS.
SUBTTL Sending Messages -- SENDQ (Maintain send queue)
;Routines to maintain the "send queue"
;Routine to enqueue a send message
; T1/ Address of message
; T2/ local port number
;Returns:
; +1 always
;CALL PIOFF!!!
;messages are queued when an attempt to send them fails due to lack
;of credit.
SENDQ: MOVEM T1,@CFSSQT(T2) ;Put it on
SETZM 0(T1)
MOVEM T1,CFSSQT(T2)
RET ;And done
;Routine to send message from send queue until exhausted or failed
; T1/ Local port
;Returns: +1 always
SSENDQ: SAVEAC <Q1,Q2>
MOVE Q1,T1 ;Copy port
DO.
SKIPN Q2,CFSSMQ(Q1) ;Any more to do?
RET ;No
; PIOFF
MOVE T2,0(Q2) ;Unlink it
MOVEM T2,CFSSMQ(Q1) ;New head
IFE. T2 ;If now empty
XMOVEI T2,CFSSMQ(Q1)
MOVEM T2,CFSSQT(Q1) ;Init it
ENDIF.
; PION
BLCAL. (SC.SMG,<CFSHST(Q1),[F.RTB+F.SPM],[VOTSZB],Q2,[CFSPRI],[0],[0]>)
IFNSK. ;If failed
; PIOFF
MOVE T1,CFSSMQ(Q1) ;Get new head
MOVEM T1,0(Q2) ;Make this one the new head
MOVEM Q2,CFSSMQ(Q1) ;
SKIPN T1 ;Was it empty?
MOVEM Q2,CFSSQT(Q1) ;yes.
; PION
RET ;And done
ENDIF.
LOOP. ;Do them all
ENDDO.
SUBTTL Queuing Message Buffers -- SCARET (Queue packet as message buffer)
;Still IFN CFSSCA
;Routine to return a packet as a message buffer
; T1/ address of buffer
SCARET: MOVE T2,.MHSCI(T1) ;Get local index
SKIPE CFSHST(T2) ;Is this slot in use?
SKIPL CFHSTS(T2) ;Still?
IFNSK. ;If not
MOVE T2,.MHDCI(T1) ;Get return address
CALLRET 0(T2) ;Return it
ENDIF.
BLCAL. (SC.RMG,<CFSHST(T2),[1],T1>)
NOP ;JUST IN CASE
RET
SUBTTL Declare a dump listener -- CFDLSN (Declare CFS dump listener)
;[7.1021] CFDLSN - Declare a cluster dump listener.
;
;This listener will set CLDWRD to non-zero when it receives a connect
;request from a remote node. Then, when this remote node crashes, PHYKLP
;will notice that a cluster dump is in progress, and issue a KLPDMP BUGHLT
;(instead of the usual KLPCVC BUGINF).
;
; Accepts no arguments
;
; CALL CFDLSN
;
;Returns:
; +1 Failure, with:
; T1=0 if no more host slots
; T1<>0 if some SCA error
; +2 Success
;
;Called at startup only from CFSJYN.
CFDLSN::SAVEQ
PIOFF ;Prevent host table interruptions
MOVSI T1,-HSTSIZ ;Size of host table
;Loop thorugh each host in the host table and listen for the request to dump.
DO. ;Loop to find free slot
SKIPE CFSHST(T1) ;Found one?
IFSKP. ;If so
SETOM CFSHST(T1) ;Mark we are listening on this port
SOS CFSHST(T1) ;And indicate that this is a dump listener
SETZM CFHSTS(T1) ;Init status
PION
HRRZ Q1,T1 ;Get index
BLCAL. (SC.LIS,<<.,LISDMP>,<.,LISDMP>,[-1],<.,CFSINT>,Q1,[0],[0]>) ;[7.1190]
IFNSK.
SETZM CFSHST(Q1) ;An error. No longer listening
BUG.(INF,CFDLSF,CFSSRV,SOFT,<CFSSRV - Failed to get dump listener>,<<T1,ERR>>,<
Cause: The call to SC.LIS to set up the dump listener failed. This system
will not participate in any cluster dump.
Action: If this problem is reproducible, set this BUGINF dumpable and submit an
SPR along with the dump and instructions on reproducing the problem.
Data: ERR - Error code returned by SC.LIS
>)
RET ;Return failure
ENDIF.
MOVEM T1,CFSHNM(Q1) ;Put CID here for now
RETSKP ;Return success
ENDIF.
AOBJN T1,TOP. ;Try the next slot
PION ;Turn on interrupts again
ENDDO. ;End of loop on CFSHST
CALLRET RETZ ;No free table entries, fail
SUBTTL Declare a listener -- CFSLSN (Declare CFS listener)
;Routine to declare a CFS listener.
;Returns:
; +1 failed
; T1=0 if no more host slots
; T1<>0 if some SCA error
;Call with CFS interlock set, please
CFSLSN::SAVEQ
PIOFF
MOVSI T1,-HSTSIZ ;SIZE OF HOST TABLE
DO. ;LOOP TO FIND FREE SLOT
SKIPE CFSHST(T1) ;FOUND ONE?
IFSKP. ;IF SO
SETOM CFSHST(T1) ;MARK WE ARE LISTENING ON THIS PORT
SETZM CFHSTS(T1) ;INIT status
PION
HRRZ Q1,T1 ;GET INDEX
BLCAL. (SC.LIS,<<.,LISNAM>,<.,LISNAM>,[-1],<.,CFSINT>,Q1,[SCRDIT],[RCRDIT]>) ;[7.1190]
IFNSK.
SETZM CFSHST(Q1) ;AN ERROR. NO LONGER LISTENING
BUG.(HLT,CFLISF,CFSSRV,SOFT,<CFSSRV - SC.LIS failed>,<<T1,ERR>>,<
Cause: The call to SC.LIS failed in CFSLSN. This indicates a possible problem
with SCAMPI.
Data: ERR - Error code returned by SC.LIS
>)
RET ;BAD
ENDIF.
MOVEM T1,CFSHNM(Q1) ;STASH I.D. HERE FOR NOW
RETSKP ;AND SUCCEED
ENDIF.
AOBJN T1,TOP. ;TRY THE NEXT
PION
ENDDO. ;END OF LOOP ON CFSHST
CALLRET RETZ ;NONE TO BE FOUND
SUBTTL Connection Management -- CHKOLD (Manage connect serial number)
;Routine to manage the connect serial number data base. CFS keeps track
;of all systems it has ever been connected to so it may prevent illegal
;reconnects.
; CALL CHKOLD
;T1/ Serial number to check
;T2/ Old/ New flag
;Returns: +1 we've never been connected
; +2 we have been
CHKOLD: SAVEP ;Get some work regs
CAIE T2,OF%OLD ;Does it think we are old?
TDZA T2,T2 ;No
MOVX T2,1B0
MOVSI P1,-HSTSIZ ;Size of the table
MOVE P2,OLDTAB ;The address of the table
DO. ;Scan it
SKIPE P3,0(P2) ;Look at this one
TDZ P3,T2 ;Do operation of delay bit
CAME P3,T1 ;Is it the one?
SKIPA
RETSKP ;Yep
ADDI P2,1 ;Next slot
AOBJN P1,TOP. ;Look at them all
ENDDO.
RET ;And say it's new
SUBTTL Connection Management -- CHKOL0 (Generate old/new bit)
;Routine to generate old/new bit
; CALL CHKOL0
; T1/ serial number to look for
;Returns: +1 T1/ old/new bit
CHKOL0: SAVEAC<Q1>
MOVEI T2,HSTSIZ
MOVE T3,OLDTAB
MOVE T4,T1 ;Copy serial number
DO.
SKIPN Q1,0(T3) ;Get next
IFSKP. ;If here
TXZ Q1,1B0 ;Ignore this for now
CAME Q1,T4 ;Is it the one we want
ANSKP. ;If so
SKIPL 0(T3) ;Delay or old?
SKIPA T1,[OF%OLD] ;Old
MOVX T1,OF%DLY ;Delayed
RET
ENDIF.
ADDI T3,1 ;Next
SOJG T2,TOP.
ENDDO.
MOVX T1,OF%NEW
RET
SUBTTL Connection Management -- PUTOLD (Install serial number)
;Routine to install a serial number.
; T2/ the number to install
;Returns: +1 always
PUTOLD: SAVEP ;Get some work regs
MOVSI P1,-HSTSIZ ;Size of the table
MOVE P2,OLDTAB ;The address of the table
DO. ;Scan it
SKIPN P4,0(P2) ;Look at this one
IFSKP. ;If occupied
TXZ P4,1B0 ;Turn off delay bit
CAME T2,P4 ;[8960] Is it what we want?
IFSKP. ;[8960] If so
MOVE P3,P2 ;Save the index
EXIT. ;And reinstall it
ENDIF.
ELSE. ;If empty
MOVE P3,P2 ;Save the slot
ENDIF.
ADDI P2,1 ;Next slot
AOBJN P1,TOP. ;Look at them all
ENDDO.
IFN DEBUG,<
; SKIPE DLYFLG ;Only do it if flag is set
> ;IFN DEBUG
TXO T2,1B0 ;Say this is under delay
MOVEM T2,0(P3) ;It is new. Store it
RET ;And say it's new
SUBTTL Connection Management -- CLRDLY (Clear delay bit in OLDTAB entries)
;Routine to clear delay bit in OLD table entries
CLRDLY: MOVEI T1,HSTSIZ ;The size
MOVE T2,OLDTAB ;The table
MOVX T3,1B0 ;The bit to clear
DO.
ANDCAM T3,0(T2) ;Clear it
ADDI T2,1 ;Next entry
SOJG T1,TOP. ;Do them all
ENDDO.
RET
SUBTTL Connection Management -- CHKDLY (Check for delayed entries)
;Routine to check if any delayed entries are still in OLDTAB
; CALL CHKDLY
; T1/ Entry to remove
;Returns: +1 Always. DLYLOK cleared if none left
;All regs preserved
CHKDLY: SAVET
SAVEAC <Q1>
MOVEI Q1,HSTSIZ ;Size of the table
MOVE T2,OLDTAB
SETZM T4 ;Assume none here
DO.
SKIPL T3,0(T2) ;[8960] Delay?
IFSKP. ;[8960] If so
TXZ T3,1B0 ;Turn off bit
CAME T3,T1 ;Is it the one we want?
AOSA T4 ;No. Say not clear yet
SETZM 0(T2) ;Yes. Clear it
ENDIF.
ADDI T2,1 ;Next entry
SOJG Q1,TOP. ;Check it all out
SKIPN T4 ;Found any?
SETZM DLYLOK ;No, all clear!
ENDDO.
RET
> ;IFN CFSSCA
SUBTTL Directory lock resource manager -- CFSLDR (Lock directory)
;Directory lock support routines. These routines are used by
;DIRECT to lock and maintain directory lock.
; T1/ Structure number
; T2/ directory number on structure
;Returns:
; +1 always
CFSLDR::STKVAR<STRA,<ARGS,2>> ;WHERE TO SAVE ARGS
MOVEM T1,STRA ;Save structure number
CALL GNAME ;Get str name
TXO T2,DRBASE
DMOVEM T1,ARGS
CSKED
CFSLOK
CALL HSHLOK ;SEE IF WE HAVE IT YET
JRST CFSDLN ;NOPE.
JN <HSHWVT,HSHCNT>,(T1),CFSDLN ;If in use or voting, do vote
INCR HSHCNT,(T1) ;NOT IN USE. GRAB IT
MOVE T3,FORKX
STOR T3,HSHFRK,(T1) ;Store new owner
MOVE T3,TODCLK ;GET NOW
MOVEM T3,HSHTIM(T1) ;STORE NOW
CALLRET CFSFAL ;SUCCEED
;Here if we can't seize it
CFSDLN: CFSULK
CFSDL0: CALL CFSSPL ;GET A REQUEST BLOCK
IFNSK. ;If can't
CALL CFSDM0 ;Release some
JRST CFSDL0 ;And try again
ENDIF.
;..
;Fill in the request block to ask for the resource
DMOVE T2,ARGS
DMOVEM T2,HSHROT(T1) ;STORE LOCK VALUES
MOVEI T2,.HTOEX ;NEED EXL
STOR T2,HSHTYP,(T1) ;STORE IT
MOVX T2,DRBASE
MOVEM T2,HSHCOD(T1) ;THE UNIQUE CODE FOR THIS
MOVE T3,TODCLK ;Now
ADDI T3,DIRTIM ;Keep it for a bit
MOVEM T3,HSHFCT(T1) ;Stash it
MOVE T3,STRA ;Get original str number
CALL CFSGTT
CALL ILLGET
SKIPE T1 ;SUCCEEDED
CALL @HSHRET(T1) ;DIDN'T NEED OUR BLOCK
RET ;AND DONE
;No space to request the thing.
CFSDM0: CALLRET SBLOCK ;Use standard routine
SUBTTL Directory lock resource manager -- CFSRDR (Unlock directory)
;Routine to unlock a directory.
; T1/ Structure number
; T2/ directory number
;Returns:
; +1 did a resched
; +2 no resched
CFSRDR::CALL GNAME
TXO T2,DRBASE
SETZM T3
CALL CFSNDO ;RELEASE IT
IFNSK. ;If can't
BUG.(CHK,DIRDNL,CFSSRV,SOFT,<CFSSRV - Directory not locked>,,<
Cause: CFSRDR was called to unlock a directory, but the directory is not
locked.
Action: If this problem is reproducible, set this BUGINF dumpable and submit an
SPR along with the dump and instructions on reproducing the problem.
>)
RET ;Wasn't locked!
ENDIF.
ECSKED
RET ;AND DONE
SUBTTL Directory lock resource manager -- CFSDAU (Acquire allocation entry)
;Directory allocation support routines. These routines create and
;maintain resources representing the allocation of directories.
;
;Acquire allocation entry
; T1/ Str # or resource node address
; T2/ Dir # or 0
; T3/ Flags,,Operation
; .CFAGT==:0 ;Get and lock current allocation
; .CFAST==:1 ;Store allocation
; .CFARL==:2 ;Release allocation table
; .CFARM==:3 ;remove entry
; .CFAUP==:4 ;Undo hold bit
; .CFAFD==:5 ; Find it
; T4/ Current allocation or -1 if none to set
; Returned allocation in T1
;return resource address in T2 is called without this
; T3/ transaction number if new block allocated
CFSDAU::ASUBR <STRN0,DIRN,ACCESS,ALLC>
HRRZS T3
CAILE T3,.CFAFD ;Still?
BUG.(HLT,CFBAFN,CFSSRV,SOFT,<CFSSRV - Bad function to CFSDAU>,,<
Cause: CFSDAU was called with an invalid function.
>)
SAVEQ ;Work regs
JRST @[IFIW!CFAGET ;Lock allocation entry and get value
IFIW!CFASTO ;Store new value and unlock
IFIW!CFAULK ;Unlock table
IFIW!CFAREM ;Remove entry
IFIW!CFAUPB ;Undo hold bit
IFIW!CFAFND](T3) ;Find
SUBTTL Directory lock resource manager -- CFAFND/CFAGET (Find/Get allocation table)
;Lock allocation table
CFAFND: TDZA T4,T4
CFAGET: MOVEI T4,1
SAVEAC<P1,P2>
MOVE P2,T4
SETZM P1
CFAG00: MOVEI Q3,.HTOEX ;Assume exclusive
TMNN CF%HLD,ACCESS ;Need it held?
MOVEI Q3,.HTOAD ;No. Share it then
CALL GETDBK
IFNSK. ;If not here...
SKIPE T2,P2 ;If finding...
AOJA P1,CFSDAO ;Go to it if not
CALLRET CFSFAL ;Fail otherwise
ENDIF.
IFNDEF CFSDUM,< ;Only if we are a real CFS node
TMNN CF%PRM,ACCESS ;Want it held?
IFSKP.
SETONE HSHKPH,(T1) ;Hold it here
ENDIF.
TMNN <HSHTWF,HSHWVT,HSHUGD>,(T1) ;[8960] Anybody else doing this?
IFSKP. ;[8960] If so
MOVE T2,T1 ;Copy address
MOVEI T1,CFGVOT ;Wait for a bit
CFSULK
CALL CFSWUP ;""
AOJA P1,CFAG00
ENDIF.
LOAD T2,HSHTYP,(T1) ;Get the type
CAML T2,Q3 ;[8960] Is it all set for us?
IFSKP. ;[8960] If not
;Here when the access is not correct
SETONE HSHTWF,(T1) ;Prevent tampering from others
MOVEI T3,0(Q3) ;Get access desired
MOVE Q1,T1 ;Save block address
DMOVE T1,HSHROT(T1) ;Get lookup stuff
AOS P1
CALL CFSUGD ;Do the upgrade
IFNSK.
SETZRO HSHTWF,(Q1) ;No longer need this
MOVEI T1,CFSRWT ;Wait a bit
MOVE T2,Q1 ;The block
SKIPN T3,HSHWTM(Q1) ;Got a wait time?
MOVEI T3,^D500 ;No invent one
ADD T3,TODCLK ;When to retry
MOVEM T3,HSHTIM(Q1)
CALL CFSWUP ;Wait a bit
DMOVE T1,Q1
JRST CFAG00 ;And do it again
ENDIF.
CFSLOK
SETZRO HSHTWF,(Q1) ;Not blocked anymore
MOVE T1,Q1
ELSE.
INCR HSHCNT,(T1) ;Yes.
ENDIF.
TMNE CF%HLD,ACCESS ;Want it held?
IFSKP. ;If not
DECR HSHCNT,(T1) ;So don't
ENDIF.
> ;IFNDEF CFSDUM
MOVE T2,FORKX ;Fork
STOR T2,HSHFRK,(T1)
MOVE T2,T1 ;Resource address
MOVE T3,HSHOP1(T1) ;Get resource count as well
MOVE T1,HSHOPT(T1) ;Get last value of allocation
CFSULK
JUMPE P1,RSKP ;If no resched, say so
RET ;And done, with a resched
;Here if we must vote
CFSDAO: CALL CFSSPC ;Get some space
IFNSK. ;If failed
CALL CFSDM0 ;Standard recovery
JRST CFAG00 ;Try again
ENDIF.
DMOVEM Q1,HSHROT(T1) ;Store indentifier
STOR Q3,HSHTYP,(T1) ;Store type needed
TMNN CF%PRM,ACCESS ;Want it held?
IFSKP.
SETONE HSHKPH,(T1) ;Keep this
ENDIF.
SETZM HSHOPT(T1) ;No optional data yet
SETZM HSHOP1(T1) ;No transaction number yet
XMOVEI T2,CFAVOK ;When we are to approve a vote
MOVEM T2,HSHOKV(T1) ;Call us here
XMOVEI T2,CFADAR ;When we get some optional data
MOVEM T2,HSHCDA(T1) ;Call us here
XMOVEI T2,CFARMV ;Disallow allocations
MOVEM T2,HSHPST(T1) ;Don't allow release
MOVE T3,STRN0 ;Get structure number
CALL CFSGTT
CALL ILLGET
SKIPE T1 ;Did we use this?
CALL @HSHRET(T1) ;No. Return it then
CFSLOK ;Lock it
DMOVE T1,Q1
CALL HSHLOK ;Find the entry
BUG.(HLT,CFSNAF,CFSSRV,SOFT,<Allocation entry not found>,,<
Cause: An allocation entry has just been created and CFSSRV can't find it in
the hash table.
>)
TMNE CF%HLD,ACCESS ;Want it held?
IFSKP. ;if not
DECR HSHCNT,(T1) ;Get rid of it
ENDIF.
SKIPN T3,HSHOP1(T1) ;[8960] Anything in here?
IFSKP. ;[8960] If so
MOVE T2,T1 ;Get resource address
MOVE T1,HSHOPT(T1) ;Get it
ELSE. ;If not
MOVE T2,ALLC ;Get new value
MOVEM T2,HSHOPT(T1) ;Stash
TMNN CF%NUL,ACCESS ;Is the value valid?
AOS HSHOP1(T1) ;Say we've been here
EXCH T1,T2
ENDIF.
CALLRET CFSFAL ;And done (we did a resched if we got here)
SUBTTL Directory lock resource manager -- CFASTO (Store new allocation value)
;CFSDAU continued.
;CFASTO - Store new value
CFASTO: CALL GETDBK ;Get block address
CFABUG: BUG.(HLT,CFANAE,CFSSRV,SOFT,<CFSSRV - No allocation entry>,,<
Cause: The caller wanted to update a directory allocation entry, and no such
entry could be found.
>)
MOVE T2,ALLC ;Get the value
MOVEM T2,HSHOPT(T1) ;Stash it
AOS HSHOP1(T1) ;And make this transaction current
CFSULK ;Unlock it
DMOVE T1,Q1
; CALLRET CFAULK ;And release it
SUBTTL Directory lock resource manager -- CFAULK (Unlock allocation entry)
;Unlock allocation entry
CFAULK: CALL GETDBK ;Get block address
CALL CFABUG
CFSULK
DMOVE T1,HSHROT(T1)
CALLRET CFSNDO ;Do it
SUBTTL Directory lock resource manager -- CFAREM (Remove allocation entry)
;Remove entry
CFAREM: CALL GETDBK ;Find the block
CALL CFABUG ;Bad!
LOAD T2,HSHCNT,(T1) ;Get current share count
SOSG T2 ;Should we do it?
IFSKP. ;If not
STOR T2,HSHCNT,(T1) ;Store new value
ELSE.
CALL CFSRMV ;remove the entry
ENDIF.
CALLRET CFSRSK ;And done
SUBTTL Directory lock resource manager -- CFAUPB (Undo keep here bit)
;Undo "keep here" bit
CFAUPB: CALL GETDBK ;Find it
CALL CFABUG ;Oops
SETZRO HSHKPH,(T1) ;Clear this
CFSULK
DMOVE T1,HSHROT(T1) ;Get lookup values
CALL CFSNDO
NOP
RET
SUBTTL Directory lock resource manager -- CFAVOK (Vote to be approved)
IFNDEF CFSDUM,< ;If doing CFS for real
;CFAULK stuff continued.
; Interrupt level support routines
;CFAVOK - Called when vote is to be approved
; T1/ vote packet
; T2/ hash packet
CFAVOK: DMOVE T3,HSHOPT(T2) ;Yes, get the stuff
DMOVEM T3,CFDAT(T1) ;Store it
SETONE CFODA,(T1) ;Say we put something here
RET ;And done
SUBTTL Directory lock resource manager -- CFADAR (Optional data present)
;Here when optional data arrives on a vote
; T1/ Hash packet
; Q1/ Vote pakcet
CFADAR: SKIPE T2,CFDT1(Q1) ;has he anything to say?
CAMG T2,HSHOP1(T1) ;A later transaction?
RET ;No
RETSKP ;yes.
SUBTTL Directory lock resource manager -- CFARMV (Voter remove entry)
;here when entry is to be removed by voter
CFARMV: JE HSHKPH,(T1),R ;If not holding, remove it
SETZRO HSHTYP,(T1) ;If holding, turn it into a place-holder
RETSKP ;And allow access
> ;IFNDEF CFSDUM
IFDEF CFSDUM,< ;If not doing CFS for real
CFADAR:
CFARMV:
CFAVOK: RET ;Dummies
> ;IFDEF CFSDUM
SUBTTL Directory lock resource manager -- GETDBK (Find resource block)
;CFSDAU continued
;Utility to find resource block
;Args in ASUBR on the stack
;Returns: +1 not found. Q1, Q2 with names
; +2 T1/ block. CFS lock locked
GETDBK: CFSLOK ;Lock it up
MOVE T1,STRN0 ;Get str number
SKIPN T2,DIRN ;Name or address
RETSKP ;Address
CALL GNAME ;Get its name
MOVE T2,DIRN ;Get directory number
TXO T2,DRBAS0
DMOVE Q1,T1 ;Save names
CALL HSHLOK
JRST CFSFAL ;Not there
RETSKP ;Found it
ENDAS.
SUBTTL File open resource manager -- CFSGFA (Acquire file opening locks)
;Routine to acquire file locks on "first opening".
;Called from GETCFL in PAGUTL.
;
; T1/ STR #
; T2/ XB address
; T3/ Access type - either: .CFOPT - Open thawed (full sharing)
; .CFOPF - Open frozen
; .CFOPR - Restricted
; .CFOPP - Promiscuous (unrestricted)
; .CFOLE - DUD
IFNDEF CFSDUM,< ;If CFS
CFSGFA::SAVEQ
STKVAR <ACCESS>
MOVE T3,[.HTOAD ;Full sharing
.HTOSH ;Read-only sharing
.HTOEX ;Exclusive
.HTOPM ;Promiscuous
1B0!.HTOEX](T3) ;Local exclusive
DMOVE Q1,T1 ;COPY ARGS
MOVEM T3,ACCESS
CALL GNAME
CFSLOK
CALL HSHLOK ;Look 'er up
IFSKP. ;If here
MOVE Q3,T1 ;Save block address
DMOVE T1,HSHROT(T1) ;Get root and qualifier
MOVE T3,ACCESS ;new access
CALL CFSUGD ;Change it
RETBAD() ;No way
; DECR HSHCNT,(Q3) ;Discount extra sharer
RETSKP ;Made it
ENDIF.
CFSULK
CALL CFSSPC ;Get some space
IFNSK. ;Error
MOVEI T1,^D30000 ;Pick up stale resources
MOVEI T2,10 ;Just do some
CALL CFSRSX ;Free up some
CALL CFSSPC ;Try again
RETBAD() ;Nope
ENDIF.
MOVE Q3,T1 ;COPY BLOCK
MOVE T2,ACCESS ;Desired access
STOR T2,HSHTYP,(T1) ;Stash it
IFL. T2 ;If want local exclusive
SETONE HSHLCL,(T1) ;Set it
ENDIF.
MOVEM Q2,HSHQAL(T1)
MOVE T2,Q1 ;STR #
CALL GNAME2
MOVEM T2,HSHROT(T1)
MOVE T3,Q1 ;Copy structure #
CALLRET CFSFCA ;DO COMMON ACQUISITION CODE
> ;IFNDEF CFSDUM
SUBTTL File open resource manager -- CFSFFL (Release file locks)
;Release file locks
;T1/ STR #
;T2/ XB address
;Returns: +1 always
IFNDEF CFSDUM,<
CFSFFL::CALL GNAME
CALL CFSNDO ;FREE IT
NOP
RET
> ;IFNDEF CFSDUM
SUBTTL File open resource manager -- CFSURA (Downgrade to promiscuous)
;Routine to "downgrade" file lock from whatever to promiscuous.
;Called when RELOFN (in PAGEM) detects all "real" openings
;are closed
; T1/ OFN
;Returns: +1 always
IFNDEF CFSDUM,<
CFSURA::SAVET
SAVEAC<Q1>
LOAD T2,STGADR,SPTH(T1) ;Get XB address
LOAD T1,STRX,(T1)
CALL GNAME
CFSLOK
CALL HSHLOK ;Look it up
IFNSK. ;This shouldn't happen
CFSULK
RET
ENDIF.
MOVE Q1,T1
DMOVE T1,HSHROT(T1) ;Get codes
MOVEI T3,.HTOPM ;New mode
CALL CFSUGD ;Do it
CALL CFNCNT
DECR HSHCNT,(Q1)
RET ;And done
> ;IFNDEF CFSDUM
;Versions of above for non-CFS
IFDEF CFSDUM,<
CFSGFA::RETSKP
CFSURA::RET
> ;IFDEF CFSDUM
SUBTTL Frozen writer resource manager -- CFSGWL (Get write access)
;Routine used by PAGEM to acquire the "write access" lock for a fil.
;This "lock" represents the writer for a frozen file.
; T1/ STR #
; T2/ XB address
;Returns:
; +1 failed. Lock owned elsewhere
; +2 success
CFSGWL::
IFDEF CFSDUM,< ;If not a real CFS
RETSKP ;Done
> ;IFDEF CFSDUM
IFNDEF CFSDUM,< ;If real
SAVEQ
DMOVE Q1,T1
CALL CFSSPC ;Get a block
IFNSK. ;If error
SETZM T1
MOVEI T2,10 ;Just do some space
CALL CFSRSX ;Failed. Free up space then
CALL CFSSPC ;Try again
RETBAD() ;Failed. No space
ENDIF.
MOVE T2,Q1 ;STR #
CALL GNAME2
MOVEM T2,HSHROT(T1) ;Stroe it
TXO Q2,FILEWL ;MARK WRITE LOCK WANTED
MOVEM Q2,HSHQAL(T1) ;Store the qualifier
MOVEI T2,.HTOEX ;EXCLUSIVE
STOR T2,HSHTYP,(T1)
MOVE T3,Q1 ;Copy str #
;CALLRET CFSFCA
;Pseudo-routine to acquire a file resource
CFSFCA: SETZM T2 ;NO RETRY
CALL CFSGTT
RETBAD() ; It didn't
SKIPE T1 ;NEED TO RETURN THE BLOCK?
CALL @HSHRET(T1) ;YES
RETSKP ;AND DONE
> ;IFNDEF CFSDUM
SUBTTL Frozen writer resource manager -- CFSFWL (Free write access)
;Free CFS file write lock
;T1/ STR #
;T2/ XB address
;Returns:
; +1 always
IFNDEF CFSDUM,<
CFSFWL::TXO T2,FILEWL ;UNQ
CALL GNAME
CALL CFSNDO ;RELEASE IT
NOP
RET
> ;IFNDEF CFSDUM
;Versions of above for non-CFS
IFDEF CFSDUM,<
CFSFFL::
CFSFWL::RET
> ;IFDEF CFSDUM
;LOCAL ROUTINE TO CLEAN UP RESOURCES AND WAIT A LITTLE BIT
SBLOCK: SETZM T1 ;Desparation. Get a bunch
MOVEI T2,CLCCNT ;Count to collect
CALL CFSRSX
MOVE T1,TODCLK
ANDI T1,377777
ADDI T1,^D300 ;SHORT SLEEP
MOVSS T1
HRRI T1,BLOCKW ;THE TEST
CALL CFSWUP ;WAIT
RET ;AND DONE
SUBTTL BAT block resource manager -- CFGBBS (Set BAT block lock)
;Routines to get and release BAT block locks.
;Get lock
; T1/ Structure number
; Returns: +1 always
IFNDEF CFSDUM,< ;If CFS
CFGBBS::ASUBR<STRNO>
CFGBB0: CALL CFSSPC ;GET SOME SPACE
IFNSK.
CALL SBLOCK ;WAIT A BIT
JRST CFGBB0 ;TRY AGAIN
ENDIF.
MOVE T2,STRNO
SETOM HSHQAL(T1) ;BAT BLOCK CODE
CALL GNAME2
MOVEM T2,HSHROT(T1)
MOVEI T2,.HTOEX ;NEED EXCLUSIVE ACCESS
STOR T2,HSHTYP,(T1) ;STASH IT
MOVE T3,STRNO
MOVE T3,STRTAB(T3)
LOAD T3,STEXL,(T3)
CALL @[ IFIW!CFSGET
IFIW!CFSGTL](T3)
CALL ILLGET
SKIPE T1 ;WANT IT RELEASED?
CALL @HSHRET(T1) ;YES
RET ;DONE
ENDAS.
SUBTTL BAT block resource manager -- CFFBBS (Release BAT block lock)
;Release BAT block lock
; T1/ Str number
; Returns: +1 always
CFFBBS::CALL GNAME
SETOM T2
CALL CFSNDO
NOP ;Who cares?
RET ;And done
> ;IFNDEF CFSDUM
;Versions of above for non-CFS
IFDEF CFSDUM,<
CFFBBS::
CFGBBS::RET
> ;IFDEF CFSDUM
SUBTTL File access token resource manager -- CFSGWT (Get write token value)
;Routines to manage the "write token".
;Fetch current value of token
; T1/ OFN
;Returns:
; +1 not here or in use. T1=0= not here. If here, T2/ 0 or 1
; +2 T1/ 0 or 1
;Called NOSKED!!!
CFSGWT::LOAD T2,STGADR,SPTH(T1) ;GET XB
TXO T2,FILEWT
LOAD T1,STRX,(T1)
CALL GNAME
CFSLOK
CALL HSHLOK ;LOOK 'ER UP
JRST [ CFSULK
JRST RETZ]
MOVE T2,TODCLK ;GET NOW
MOVEM T2,HSHTIM(T1) ;STAMP IT
LOAD T2,HSHCNT,(T1)
LOAD T1,HSHTYP,(T1) ;GET TYPE
JUMPE T1,[ CFSULK ;If a place-holder
JRST RETZ] ; Treat as if not here
CAIE T1,.HTOEX ;EXCLUSIVE?
TDZA T1,T1 ;No.
MOVEI T1,1 ;Yes
CFSULK
IFG. T2
MOVE T2,T1 ;GET ACCESS TYPE
JRST RETO ;AND DONE
ENDIF.
RETSKP ;AND DONE
SUBTTL File access token resource manager -- CFSAWP/CFSAWT (Acquire write token)
;Routine to acquire the proper "write token".
; T1/ OFN
; T2/ type needed
; 0=) shared, <>0=) exclusive
;Returns: +1 always
;Called NOSKED
;CFSAWP - reserve to this processor
;CFSAWT - don't reserve to this processor
CFSAWP::TDZA T3,T3 ;LEAVE IT LOCKED
CFSAWT::MOVEI T3,1 ;UNLOCK WHEN DONE
TMNE OFNDMO,SPTH(T1)
RET ;If dismounted, let it go
CAIGE T1,NOFN ;[7247] Is the OFN in range?
TLNE T1,-1 ;[7247] And is it positioned correctly?
BUG.(HLT,CFSION,CFSSRV,SOFT,<CFSSRV - Invalid OFN number>,,<
Cause: CFSAWT or CFSAWP has been called with an invalid OFN number. These
routines expect the OFN number to be in the right half of T1 and to be
in the expected range of values. The caller in the dump should be
examined to determine why it passed a bad OFN number.
>) ;[7247] No, report error
SAVEP5 ;REGS
STKVAR <WTFLAG,LKFLAG>
MOVEM T3,LKFLAG ;Save the flag
SKIPE T2 ;Check what kind we need
SKIPA T2,[.HTOEX] ;Exclusive
MOVEI T2,.HTOAD ;Full read-share
DMOVE P1,T1 ;SAVE OFN and access type
IFNDEF CFSDUM,< ;If a real CFS monitor, do this as well
CFSAWL:
DO.
LOAD T1,STRX,(P1) ;GET STR NAME
CFSLOK
TMNE SPTFO,(P1) ;Being forced out?
SKIPGE DDPFRK ;Is this not DDMP
IFSKP. ;If so
MOVS T1,P1 ;Get OFN
HRRI T1,WTFOD ;wait here a bit
CFSULK
CALL CFSWUP ;Wait here
LOOP. ;Try again
ENDIF.
ENDDO.
MOVE T2,CFSOFN ;Get OFN table address
ADDI T2,0(P1) ;See if we know about this one yet
SKIPN T1,0(T2) ;[7247] Do we?
JRST CFSAW1 ;[7247] Go on if not around
;[7247] Continue here if the block already exists or is cached and being reused
CFSAWH: ;[7247]
IFN DEBUG,<
HRRZ T2,P1 ;Isolate OFN
CAME T2,HSHCOD(T1) ;Quick check for consistency
BUG.(HLT,CFSBTP,CFSSRV,SOFT,<CFSSRV - Bad token packet>,,<
Cause: CFSAWT has been called to acquire an access token for an OFN. The OFN
access token already exists on this system and the block address is in
CFSOFN. But the OFN recorded in the block does not match the one
passed into CFSAWT.
>)
> ;IFN DEBUG
SKIPLE HSHPST(T1) ;[8960][7247] This one in use and good?
IFSKP. ;[8960] If not
XMOVEI T2,CFSDWT ;Where to do it
MOVEM T2,HSHPST(T1) ;Fix it up (make it a usable block)
ENDIF.
MOVE P5,T1 ;Save pointer
INCR HSHLKF,(P5) ;Lock it
CFSUGX: TMNN <HSHTWF,HSHUGD,HSHWVT>,(P5) ;[8960] Waiting for it somewhere else?
IFSKP. ;[8960] If any of the above
CFSULK
MOVEI T1,CFGVOT ;And wait for vote to complete
SETOM WTFLAG ;We didn't set HSHTWF
JRST CFSUGW ;And wait a bit
ENDIF.
LOAD T3,HSHTYP,(P5) ;Get type we now hold
LOAD T1,STRX,(P1) ;Get STR #
MOVE T1,STRTAB(T1) ;Get SDB
TMNN STEXL,(T1) ;[8960] Is this exclusive?
IFSKP. ;[8960] If so
MOVEI T3,.HTOEX ;Upgrade it now to the maximum
STOR T3,HSHTYP,(P5) ;And store it
ENDIF.
CAIE T3,.HTOEX ;[8960] Do we hold exclusive rights?
IFSKP. ;[8960] If so
REPEAT 0,< ;Not using anti-hog device now
TMNN HSHRFF,(P5) ;Someone waiting?
IFSKP. ;If so
MOVE T1,HSHTIM(P5) ;Get last transition time
ADDI T1,MAXHLT ;Get constraint
CAML T1,TODCLK ;Held it too long?
IFSKP. ;If so
SETONE HSHTWF,(P5) ;lock it
SETZM WTFLAG ;Say we did it
MOVEI T1,CFSRWT ;Just stall a bit
CFSULK
JRST CFSUGW ;Do it
ENDIF.
ENDIF.
> ;REPEAT 0
DECR HSHLKF,(P5)
MOVEI P2,0(T3) ;Copy type
SKIPE LKFLAG ;Check the lock flag
JRST RTYPE ;All set. Finish up
INCR HSHCNT,(P5) ;If hold do it
JRST RTYPE ;And set the state
ENDIF.
;Found the entry. See if we can upgrade it
SETONE HSHTWF,(P5) ;Set flag to prevent others from getting in
SETZM WTFLAG
DMOVE T1,HSHROT(P5) ;CODES
MOVEI T3,0(P2) ;MUST WANT EXCLUSIVE
LOAD T4,HSHTYP,(P5) ;Save state we have it in now
CALL CFSUGD ;Must call with the interlock set!!!
IFSKP.
CFSLOK
SETZRO <HSHRFF,HSHTWF>,(P5)
MOVE T1,TODCLK ;Get now
ADDI T1,WRTTIM ;fairness time
SKIPN P4 ;Update only if we just seized it
MOVEM T1,HSHFCT(P5)
DECR HSHLKF,(P5)
SKIPN LKFLAG ;Want to hold?
IFSKP. ;If not
TMNN HSHCNT,(P5) ;Any count?
CALL CFNCNT ;No!
DECR HSHCNT,(P5) ; release the hold
ENDIF.
TMNN HSHCNT,(P5) ;is it still locked here?
SKIPN HSHNBT(P5) ;If no, anyone to notify?
IFSKP. ;If so
MOVE T1,P5 ;Copy address
CALL CFNOHS ;Notify anyone rejected in the interim
ENDIF.
TMNN HSHODA,(P5) ;[8960] Any optional data?
IFSKP. ;[8960] If so,
MOVE T2,HSHOPT(P5) ;Get it
; SKIPE HSHOP1(P5) ;Store only if from the owner
MOVEM T2,OFNLEN(P1) ;Update length information
SETZRO HSHODA,(P5) ;And no longer valid
ENDIF.
JRST RTYPE ;And go set the state
ENDIF.
SETZRO HSHTWF,(P5) ;Clear it now
SETOM WTFLAG ;And say we didn't set it
MOVEI T1,CFSRWT ;Do this one if here
SKIPN T2,HSHWTM(P5) ;[8960] gave us a time to wait?
IFSKP. ;[8960] If so
CAIGE T2,^D20 ;Wait at least this long
MOVEI T2,^D20 ;""
JRST CFSUGT ;[8960] Enter below
ENDIF.
;Here when couldn't upgrade an entry
CFSUGW: MOVEI T2,^D500 ;Wait a long time if here (we should be
; notified via the "undo" when to try again
CFSUGT: ADD T2,TODCLK ;[8960] Wait time
MOVEM T2,HSHTIM(P5)
MOVE T2,P5 ;Block address
CALL CFSWUP ;Do the wait
CFSLOK ;Lock 'er up
SKIPE WTFLAG ;[8960] Did we set the wait flag?
IFSKP. ;[8960] If so
SETZRO HSHTWF,(P5)
ENDIF.
SKIPG HSHPST(P5) ;[8960][7247] Has it been released or uncached?
IFSKP. ;[8960] If not
SETZRO <HSHRTY,HSHVRS>,(P5)
DECR HSHLKF,(P5) ;No longer need this lock
CFSULK ;Don't need this now
JRST CFSAWL ;And go to the top
ENDIF.
LOAD T1,HSHLKF,(P5) ;Get lock value
SOJE T1,CFSUGL ;[8960] Decrement lock value, are we the last?
STOR T1,HSHLKF,(P5) ;We are not the last, replace new count
JRST CFSFAL ;Unlock and return
;[8960] Here when we are the last (HSKLKF=1)
CFSUGL: MOVE T1,HSHCOD(P5) ;[8960] Get the OFN
ADD T1,CFSOFN ;Point to OFN table entry
SETZM 0(T1) ;Clear it
;[7247] Here when a call was made to CFSUWT or CFSUNC while block was locked
SKIPL HSHPST(P5) ;[7247] Was a token uncache attempted?
IFSKP. ;[7247] Yes
SETZRO HSHTAM,(P5) ;[7247] Uncache just in case it was set
SOS CFACCT ;[7247] Decrement currently cached count
MOVE T1,P5 ;[7247] Get resource block address
CALL CFSRMV ;[7247] (T1/T1,T2)Remove it
CALLRET CFSFAL ;[7247] And return
ENDIF. ;[7247]
;[7247] Here when a call was made to CFSCWT while block was locked
SUB T1,CFSOFN ;[7247] Get OFN back again
TMNN OFNDMO,SPTH(T1) ;[7247] Is it dismounted?
IFSKP. ;[7247] Yes, destroy token
MOVE T1,P5 ;[7247] Get resource block address
CALL CFSRMV ;[7247] (T1/T1,T2)Remove it
ELSE. ;[7247] Not dismounted, cache it
SETZRO <HSHCNT>,(P5) ;[7247] Clear the count but KEEP bit stays set
SETONE <HSHTAM,HSHKPH>,(P5) ;[7.1029][7247] Set the cache bit and keep bit
SETZM HSHPST(P5) ;[7247] No more post address
AOS CFACCT ;[7247] Increment the number we currently have
ENDIF. ;[7247]
CALLRET CFSFAL
;test for above
CFGVOT: LOAD T1,FKST2,(Q3)
TMNE <HSHTWF,HSHWVT,HSHUGD>,(T1) ;Still waiting
JRST 0(4) ;Yepper
JRST 1(4) ;No. Try now
;Here to add an entry. Should happen only once in a while
CFSAW1:
LOAD T1,STRX,(P1) ;Get STR #
LOAD T2,STGADR,SPTH(P1) ;Get XB address
IFN DEBUG,< ;Make sure all is OK
SKIPN T2 ;Is it?
BUG.(HLT,CFNLTK,CFSSRV,SOFT,<CFSSRV - Null disk address given to CFSAWT>,,<
Cause: A call was made to create an OFN access token but SPTH for the OFN is
not set up.
>)
> ;IFN DEBUG
TXO T2,FILEWT ;Set token bit
CALL GNAME ;Get the name of the structure
DMOVE P3,T1 ;Save these for later
CALL HSHLOK ;[7247] (T1,T2/T1,T2) Look for the token
IFSKP. ;[7247] Found so this one better be cached
TMNN HSHTAM,(T1) ;[7247] Is it?
BUG.(HLT,CFSTCM,CFSSRV,SOFT,<CFSSRV - Access token cached but not marked>,,<
Cause: A cached access token is being requested. As expected, it is in the
hash table and not in CFSOFN. But HSHTAM is not set as expected.
>) ;[7247] No, report error
CAME P1,HSHCOD(T1) ;[7247] Is this the same OFN?
BUG.(HLT,CFAOFM,CFSSRV,SOFT,<CFSSRV - OFN mismatch in cached token>,,<
Cause: A cached access token has been found for a certain OFN but the OFN
stored in the hash block does not agree.
>) ;[7247] No, report error
MOVE T2,CFSOFN ;[7247] Get OFN table address
ADDI T2,0(P1) ;[7247] Offset into table for this OFN
MOVEM T1,0(T2) ;[7247] Store token block address in table
SETZRO HSHTAM,(T1) ;[7247] Not cached anymore
SETONE HSHKPH,(T1) ;[7247] No purging this entry
XMOVEI T2,CFSDWT ;[7247] Get correct post address
MOVEM T2,HSHPST(T1) ;[7247] Fix it up (make it a usable block)
SOS CFACCT ;[7247] One less token currently cached
AOS CFACTO ;[7247] One more cache hit
JRST CFSAWH ;[7247] Continue at "found" code
ENDIF. ;[7247]
CFSULK ;[7247] Free CFS lock
DO.
CALL CFSSPC ;GET SOME SPACE
IFSKP. <EXIT.>
CALL CFSDM0 ;Clean up and pause
LOOP.
ENDDO.
DMOVEM P3,HSHROT(T1) ;SAVE CODES
STOR P2,HSHTYP,(T1) ;STASH IT
SETONE HSHKPH,(T1) ;No purging this entry
HRRZM P1,HSHCOD(T1) ;SAVE OFN AS CODE
XMOVEI T2,CFSDWT
MOVE P5,T1 ;Save block address (to get optional data)
MOVEM T2,HSHPST(T1) ;WHERE TO GO WHEN RELEASED
XMOVEI T2,CFSOVT ;Where to go when vote is approved
MOVEM T2,HSHOKV(T1) ;Store it
XMOVEI T2,CFSDAR ;Data arrived
MOVEM T2,HSHCDA(T1) ;Stash it as well
SETZM HSHOP1(T1) ;No transaction number yet
MOVE T3,CFSOFN ;The OFN table
ADDI T3,0(P1) ;Point to this entry
MOVEM T1,0(T3) ;Stash it for others to see
LOAD T3,STRX,(P1) ;Get STR #
MOVE T3,STRTAB(T3) ;Get SDB
LOAD T3,STEXL,(T3) ;Get shared/exclusive bit
CALL @[ IFIW!CFSGET
IFIW!CFSGTL](T3)
CALL ILLGET
MOVE T2,TODCLK ;Get now
ADDI T2,WRTTIM ;"Fairness" time
MOVEM T2,HSHFCT(P5) ;Stash it
TMNN HSHODA,(P5) ;[8960] Any optional data?
IFSKP. ;[8960] If so,
MOVE T2,HSHOPT(P5) ;Get it
MOVEM T2,OFNLEN(P1) ;Update length information
SETZRO HSHODA,(P5) ;And no longer valid
ELSE.
MOVE T2,OFNLEN(P1) ;Get our value
MOVEM T2,HSHOPT(P5) ;Stash it
AOS HSHOP1(P5) ;And init transaction number
ENDIF.
SKIPE T1
CALL @HSHRET(T1) ;?????
SKIPN LKFLAG ;Hold or no?
IFSKP. ;If no
DMOVE T1,P3 ;CODES
CALL CFSNDO ;RELEASE IT
NOP
ENDIF.
CFSLOK
> ;IFNDEF CFSDUM
;Here when WT is seized. Set status in SPT
RTYPE: JE <HSHKPH>,(P5),NOKEEP ;[7.1029] We must exit with the keep bit set!
MOVEI P2,0(P2) ;GET ACCESS TYPE
CAIE P2,.HTOEX ;EXCLUSIVE?
SKIPA T1,[.SPSRD] ;NO
MOVEI T1,.SPSWR ;YES
STOR T1,SPTST,(P1)
JRST CFSFAL ;Done
NOKEEP: BUG.(HLT,CFKBNS,CFSSRV,SOFT,<CFSSRV - Keep bit not set>,,<
Cause: CFSAWT/CFSAWP was called to get a CFS resource block for a token. This
routine ALWAYS sets the HSHKPH bit when it obtains this token. This
BUGHLT was arrived at when the routine was returning to its caller and
the keep bit was not set. The dump should reveal how the keep bit got
cleared or who cleared it.
>) ;[7.1029] Keep bit not set?????
ENDSV.
SUBTTL File access token resource manager -- CFSDWT (Write token revoked)
;HSHPST callback routine
;Here when write token is revoked
;Must queue requesu for background fork to invalidate pages
CFSDWT:
IFNDEF CFSDUM,< ;Only if a full CFS
JE HSHTYP,(T1),RSKP ;If a place-holder, allow it now
MOVE T2,HSHCOD(T1) ;GET OFN
SETONE SPTFR,(T2) ;SAY WE NEED IT FORCED OUT
LOAD T3,HSHTYP,(T1) ;Get the type we own
CAIE T3,.HTOEX ;Exclusive?
IFSKP. ;If so
LOAD T3,HSHVTP,(T1) ;Get type requested
CAIN T3,.HTOEX ;Not exclusive?
ANSKP. ;If so
SETZRO SPTSR,(T2) ;Say so
ENDIF.
AOS DDCFSF ;Get DDMP awake
IDIVI T2,^D36 ;Get the bit for this OFN
MOVE T3,BITS(T3) ;Get the proper bit
IORM T3,OFNCFS(T2) ;Set the bit for DDMP
; SETONE SCDDP ;Make sure
SETZM T1 ;Indicate wait
> ;IFNDEF CFSDUM
RETSKP ;AND DONE
SUBTTL File access token resource manager -- CFSOVT (Approve sharing of OFN resource)
;Here when we will approve the sharing of an OFN resource.
; T1/ vote packet
; T2/ hash packet
;Called from CFSRTV
;Returns: +1 with vote packet updated
;HSHOKV callback
CFSOVT:
IFN CFSSCA,<
SKIPN HSHOP1(T2) ;Anything here?
IFSKP. ;If so
DMOVE T3,HSHOPT(T2) ;Get opt data
DMOVEM T3,CFDAT(T1) ;Yes. Store in vote packet
SETONE CFODA,(T1) ;And say so
ELSE.
SETZM CFDT1(T1)
ENDIF.
TMNE HSHBTF,(T2) ;Is this a bit table OFN?
CALL SNDFRC ;Send the STR free count
> ;IFN CFSSCA
RET ;And done
SUBTTL File access token resource manager -- CFSGOC (Get count of resource sharers)
;Routine to get count of resource sharers.
; T1/ OFN
;Returns: +1 not here
; +2 T1/ count
CFSGOC::
IFNDEF CFSDUM,< ;If CFS
ADD T1,CFSOFN ;Point to entry in table
SKIPN T1,0(T1) ;Here?
IFSKP. ;If so
LOAD T1,HSHCNT,(T1) ;Get count
RETSKP ;Found it
ENDIF.
> ;IFNDEF CFSDUM
RET ;Not here
SUBTTL File access token resource manager -- CFSDAR (Optional data for access token)
;Here when optional data arrives for an access token
; T1/ HSH node
; Q1/ vote packet
;Returns: +1 forget the data
; +2 store it
IFN CFSSCA,<
CFSDAR: TMNN HSHBTF,(T1) ;Is this for a bit table?
IFSKP. ;If so
SKIPN T2,CFDST1(Q1) ;Any STR data?
ANSKP. ;If so
MOVE T3,HSHCOD(T1) ;Get the OFN
LOAD T3,STRX,(T3) ;Get STR #
MOVE T4,T3
ADD T4,CFSSTR ;Get local transaction count
CAMG T2,0(T4) ;Is the new one greater?
ANSKP. ;If so
MOVEM T2,0(T4) ;Update our transaction number
MOVE T4,CFDST0(Q1) ;Get free count
CALL STOFRC ;Store it (T3,T4)
ENDIF.
CALLRET CFADAR ;And done
> ;IFN CFSSCA
SUBTTL File access token resource manager -- CFSFWT (Free write token)
;Routine to free up write token resource
; T1/ The OFN
;Returns:
; +1 always
CFSFWT::
STKVAR <TROOT,TQAL,TOFN>;[7247]
CFSLOK ;[7247] Lock up the CFS database
IFNDEF CFSDUM,<
MOVEM T1,TOFN ;[7247] Save the OFN
LOAD T2,STGADR,SPTH(T1)
TXO T2,FILEWT
LOAD T1,STRX,(T1)
CALL GNAME
MOVEM T1,TROOT ;[7247] Save the root...
MOVEM T2,TQAL ;[7247] ...and qualifier
CALL CFSNDS ;Free it
NOP
DO. ;[7247]
MOVE T1,TROOT ;[7247] Get root...
MOVE T2,TQAL ;[7247] ...and qualifier
CALL HSHLOK ;[7247] (T1,T2/T1,T2) Find the resource block
IFNSK. ;[7247] Not found
MOVE T2,TOFN ;[7247] Get the OFN again
TMNE OFNCSH,(T2) ;[7247] Is this OFN cached?
BUG.(HLT,CFWTNF,CFSSRV,SOFT,<CFSSRV - Cached OFN not found when freed>,,<
Cause: CFSFWT was called to free the file access token for an OFN and the OFN
is cached. But the call to HSHLOK did not find the resource block for
the file access token. One should be there.
>) ;[7247] Yes so it should be in hash table!
JRST CFSFAL ;[7247] Return success and unlock CFS database
ENDIF. ;[7247]
;[7247] Now we must check to see if the token should be recached or removed.
;[7247] First, the share count must be checked to see if the token is
;[7247] eligible for removal. If the count is 1, and SPTFR is set, then this
;[7247] really is the last sharer of the token. This is because CFSRMX does
;[7247] an INCR of HSHCNT. In this case, CFSFDF is called to notify the other
;[7247] side and then the token is recached or removed. If the share count is
;[7247] 0, then the token is also eligible. Otherwise, no action is taken.
LOAD T2,HSHCNT,(T1) ;[7247] Get number of sharers
SKIPN T2 ;[7247] Are we the last one?
EXIT. ;[7247] Yes, continue below
CAIE T2,1 ;[7247] Is the share count 1?
JRST CFSFAL ;[7247] No, just return now
MOVE T2,TOFN ;[7247] Get the OFN again
TMNN OFNCSH,(T2) ;[7247] Is this OFN cached?
JRST CFSFAL ;[7247] No, just return
TMNN SPTFR,(T2) ;[7247] Someone waiting for us?
JRST CFSFAL ;[7247] No, just return
;[7247] At this point, OFN is cached, share count is 1, and SPTFR is set
MOVE T3,T2 ;[7247] Copy OFN
IDIVI T3,^D36 ;[7247] Compute the word it is in
MOVE T4,BITS(T4) ;[7247] Get the bit
ANDCAM T4,OFNCFS(T3) ;[7247] Zap the bit
MOVE T1,T2 ;[7247] Get back OFN
SETONE SPTFO,(T1) ;[7247] Lock out others
CFSULK ;[7247] Unlock CFS database for a moment
CALL CFSFDF ;[7247] Tell the other system they have it
NOP ;[7247]
CFSLOK ;[7247] Lock up everything again
MOVE T1,TOFN ;[7247] Get the OFN again
SETZRO SPTFO,(T1) ;[7247] Clear the lock
LOOP. ;[7247] Check everything again
ENDDO. ;[7247]
SKIPL HSHPST(T1) ;[7247] Was a token uncache attempted?
IFSKP. ;[7247] Yes
SETZRO HSHTAM,(T1) ;[7247] Uncache just in case it was set
SOS CFACCT ;[7247] Decrement currently cached count
CALL CFSRMV ;[7247] (T1/T1,T2)Remove it
CALLRET CFSFAL ;[7247] And return
ENDIF. ;[7247]
MOVE T2,TOFN ;[7247] Get the OFN again
TMNN OFNCSH,(T2) ;[7247] Is this OFN cached?
IFSKP. ;[7247] Yes - recache the file access token then
ADD T2,CFSOFN ;[7247] Point to OFN table entry
SETZM 0(T2) ;[7247] Clear entry in OFN table
TMNE HSHTAM,(T1) ;[7247] Already cached?
ANSKP. ;[7247] No so re-cache it now
SETZRO <HSHCNT>,(T1);[7247] Clear the count but KEEP bit stays set
SETONE <HSHTAM,HSHKPH>,(T1) ;[7.1029][7247] Set the cache bit and the keep bit
SETZM HSHPST(T1) ;[7247] No more post address either
AOS CFACCT ;[7247] Increment the count of cached tokens
ENDIF. ;[7247]
> ;IFNDEF CFSDUM
JRST CFSFAL ;[7247] Return success and unlock CFS database
ENDSV. ;[7247]
SUBTTL File access token resource manager -- CFSUWT/CFSCWT (Release/Cache access token)
;[7247] CFSCWT:
;[7247] Routine called when a file is closed to cache the access token
;[7247]
;[7247] CFSUWT:
;[7247] Routine called by INVOFN when a structure is dismounted to destroy
;[7247] the file access token.
;[7247]
;[7247] Both routines expect the following:
; T1/ STR #
; T2/ XB address
;Returns: +1 always
IFDEF CFSDUM,< ;[7247]
CFSCWT:: ;[7247]
CFSUWT:: RET ;[7247]
> ;[7247]
IFNDEF CFSDUM,< ;[7247]
CFSCWT::ASUBR <STRN0,XB> ;[7247]
SAVEAC <Q1> ;[7247]
SETZ Q1, ;[7247] Cache the file access token
JRST CFSUW0 ;[7247]
CFSUWT::ASUBR <STRN0,XB> ;[7247]
SAVEAC <Q1> ;[7247]
SETO Q1, ;[7247] Destroy the file access token
CFSUW0: TXO T2,FILEWT ;Access token
CALL GNAME
CFSLOK
CALL HSHLOK ;Look it up
JRST CFSFAL ;Not here
TMNE HSHTAM,(T1) ;[7247] Is this a cached token?
JRST CFSFAL ;[7247] Yes, so don't need to release it
MOVE T2,HSHCOD(T1) ;Get the OFN
TMNN SPTFR,(T2) ;[8960] Someone waiting for us?
IFSKP. ;[8960] If so
CFSULK
MOVE T3,T2 ;Copy
IDIVI T3,^D36 ;Compute the word it is in
MOVE T4,BITS(T4) ;Get the bit
ANDCAM T4,OFNCFS(T3) ;Zap the bit
MOVE T1,T2
CALL CFSFDF ;Try now
NOP
MOVE T1,STRN0
MOVE T2,XB
JRST CFSUW0 ;And do it again
ENDIF.
PUSH P,T1 ;Save packet
CALL CFNOHS ;Notify any others
POP P,T1
TMNN HSHLKF,(T1) ;[8960] Now interlocked?
IFSKP. ;[8960] If so
SETZRO <HSHTYP,HSHCNT>,(T1) ;[7247] Clear type and count but not KEEP
SKIPL HSHPST(T1) ;[7247] Has an uncache been attemped already?
MOVEM Q1,HSHPST(T1) ;[7247] No, so set release flag in post address
JRST CFSFAL ;And give it up
ENDIF.
MOVE T3,HSHCOD(T1) ;Get OFN again
ADD T3,CFSOFN ;Point to entry in table
SKIPN 0(T3) ;Is one here?
BUG.(HLT,CFSNOT,CFSSRV,SOFT,<CFSSRV - OFN token table and hash table disagree>,,<
Cause: CFSSRV is trying to remove a file access token and has found the token
in the hash table but not in the OFN token table. This indicates that
one of the data bases is incorrect.
>)
SETZM 0(T3) ;Clear entry in OFN table
SKIPL Q1 ;[7247] Want to cache the token?
IFSKP. ;[7247]
CALL CFSRMV ;[7247] (T1/T1,T2)No, remove it
ELSE. ;[7247] Yes
;[7247] Now cache the token
SETZRO <HSHCNT>,(T1) ;[7247] Clear the count but KEEP bit stays set
SETONE <HSHTAM,HSHKPH>,(T1) ;[7.1029][7247] Set the cache bit and the keep bit
SKIPL HSHPST(T1) ;[7247] Has an uncache been attemped already?
SETZM HSHPST(T1) ;[7247] No, so clear post address
AOS CFACCT ;[7247] Increment the number we currently have
ENDIF. ;[7247]
JRST CFSFAL ;And done
ENDAS.
> ;IFNDEF CFSDUM
;Here when DDMP failed to do the flush
; T1/ the OFN
CFSNFO::SETONE SCDDP ;Try again
CALLRET SKDRUN ;Make the scheduler run
;Debugging routine called from DASOFN
;This is called when an OFN is being released to see if the file
;access token has been deleted. If not, we will BUGHLT.
; T1/ OFN
CFSCON::
IFDEF CFSDUM,<RET>
IFNDEF CFSDUM,<
SAVEAC<T1> ;Save the OFN
MOVE T2,CFSOFN ;See if it is in the OFN table
ADDI T2,0(T1)
SKIPE 0(T2) ;Is it?
IFSKP. ;If not
LOAD T2,STGADR,SPTH(T1) ;Get XB address
TXO T2,FILEWT
LOAD T1,STRX,(T1) ;Get structure number
CALL GNAME ;Get name
CFSLOK ;Lock it up
CALL HSHLOK ;[7247] Look it up
IFSKP. ;[7247] It is here!
TMNN HSHTAM,(T1) ;[7247] Is it cached?
CFSCND: BUG.(HLT,CFSTND,CFSSRV,SOFT,<CFSSRV - Access token not deleted>,,<
Cause: CFSCON was called to verify that an access token has been deleted
before an OFN is released. This BUGHLT indicates that the token has not
been deleted or cached.
>) ;[7247] Found but not cached - error!
ENDIF. ;[7247]
CFSULK ;[7247] All is ok - free the lock
RET ;[7247] And done
ENDIF. ;[7247]
TMNN OFNCSH,(T1) ;[7247] Not deleted - is this OFN cached?
JRST CFSCND ;[7247] No - error!
RET ;[7247] Yes, so it is ok
> ;IFNDEF CFSDUM
SUBTTL File access token resource manager -- CFSUNC (Uncache token)
;[7247] Routine called when an OFN is being deleted and the access token
;[7247] should be uncached. This is called from DASOFN.
;[7247]
;[7247] Accepts:
;[7247] T1/ OFN
;[7247]
;[7247] Returns: +1 always with T1 preserved
CFSUNC::TMNE OFNDMO,SPTH(T1) ;[7247]
RET ;[7247] If dismounted, let it go
SAVEAC <T1> ;[7247] Save OFN
STKVAR <UCOFN> ;[7247] Location to hold OFN to uncache
MOVEM T1,UCOFN ;[7247] Save OFN to uncache
LOAD T2,STGADR,SPTH(T1) ;[7247] Get XB address
TXO T2,FILEWT ;[7247] Set token bit
LOAD T1,STRX,(T1) ;[7247] Get structure number
CALL GNAME ;[7247] (T1/T1) Get the name of the structure
CFSLOK ;[7247] Lock up the CFS database
CALL HSHLOK ;[7247] (T1,T2/T1,T2) Look for token
BUG.(HLT,CFCTNF,CFSSRV,SOFT,<CFSSRV - Could not find cached token while uncaching>,,<
Cause: CFSUNC has been called to uncache the token for a certain OFN. The
file access token should have been cached and in the hash table but it
was not found. To diagnose the problem, attempt to locate the token in
question and find out where it is (probably on the free list). It will
not be easy to determine how the token got there.
>) ;[7247] Not found - error!!
TMNN HSHLKF,(T1) ;[8960][7247] Now interlocked?
IFSKP. ;[8960][7247] If so
SETZRO <HSHTYP,HSHCNT>,(T1) ;[7247] Clear status bits but not KEEP
SETOM HSHPST(T1) ;[7247] Set to indicate that uncache attempted
JRST CFSFAL ;[7247] Return
ENDIF. ;[7247]
TMNN HSHTAM,(T1) ;[7247] Is it cached?
BUG.(HLT,CFSUCN,CFSSRV,SOFT,<CFSSRV - Uncaching non-cached token>,,<
Cause: CFSUNC has been called to uncache the token for a certain OFN. We
found the access token for the OFN but it is not cached.
>) ;[7247] No, error
MOVE T2,HSHCOD(T1) ;[7247] Get the OFN described by this token
CAME T2,UCOFN ;[7247] Does it match the one to be uncached?
BUG.(HLT,CFSUCM,CFSSRV,SOFT,<CFSSRV - Uncaching mismatch>,,<
Cause: CFSUNC has been called to uncache the token for a certain OFN. We
found the access token for the OFN but the OFN stored in the resource
block does not match the one we should be uncaching.
>) ;[7247] No - error
SETZRO HSHTAM,(T1) ;[7247] Uncache just in case it was set
SOS CFACCT ;[7247] Decrement currently cached count
CALL CFSRMV ;[7247] (T1/T1,T2) Remove entry
JRST CFSFAL ;[7247] Unlock the database and return
ENDSV. ;[7247]
SUBTTL File access token resource manager -- CFSBOW (Broadcast OFN update)
;Broadcasting routines
;CFS broadcasts information about certain events. Any braodcast
;other than a vote is done using CFSBRD.
;Here when PAGEM is about to update an OFN
;This event is broadcast so that if this system crashes before
;it can pass on access to the file, the next user will know to
;validate the XB before using it. Note this technique also elimiates
;the need for an optional data item on the access token reply to
;indicate that the OFN needs validating!
; T1/ OFN
IFNDEF CFSDUM,< ;Only need this for full CFS
CFSBOW::SKIPN CFSHCT ;Anybody out there?
RET ;No
LOAD T2,STGADR,SPTH(T1) ;Get XB address
LOAD T1,STRX,(T1) ;Get structure number
TSTRMT ;Is it a shared structure?
RET ;No. All done then
TXO T2,FILEWT
CALL GNAME ;Get the name
;Now send message to each node that is up
BLCAL. (CFSBRD,<T1,T2,[.CFBOW],[0]>) ;Do the braodcast
RET ;And done
SUBTTL File access token resource manager -- CFSBEF (Broadcast EOF)
;CFSBRD routines, continued
;Routine to broadcast EOF pointer on a file close or CHFDB%.
;This is broadcast so that the OFNLEN entries on other systems will
;be correct over a crash of this system. Since the FDB will be updated
;on the close, it is essential that sharers of this file have the
;correct EOF value.
;
;Accepts: T1/ OFN to do
;
;This routine does not expect to be called from interrupt level so
;it will protect itself via CFSLOK and CFSULK.
;
;This routine is called from DSKCLZ upon a CLOSF% of a file that has
;a window page setup and is open for write. In this case, the FDB
;will be updated with the correct length and CFSBEF will be called to
;broadcast it to the other systems in the cluster. This covers the case
;of sequential I/O EOF being broadcast.
;
;This routine is also called from CHFDB% after the FDB has been written
;to disk. The file must be open at the time of the CHFDB%. The broadcast
;is done in this case because any entry can be written into the FDB with
;CHFDB% without having the disk get updated (CF%NUD). So, the .FBSIZ
;field could have been written with CF%NUD. Therefore, in order to insure
;that the file size is broadcast, CFSBEF must be called whenever the
;directory is updated to disk from CHFDB% regardless of which specific field
;of the FDB was changed. This covers the case of random (PMAP%) I/O being
;broadcast since CHFDB% is the method by which the EOF is to be updated.
CFSBEF::SAVEAC<P1,P2> ;Get some regs
SKIPN P1,OFNLEN(T1) ;Get EOF pointer
RET ;None here
LOAD P2,SPTST,(T1) ;Get state
CAIE P2,.SPSWR ;Are we the owner?
RET ;No, don't broadcast anything
CFSLOK ;Yes, lock CFS database
MOVE T2,T1 ;Get the OFN
ADD T2,CFSOFN ;Point to entry in table
SKIPN T2,0(T2) ;Here?
BUG.(HLT,CFSBNO,CFSSRV,SOFT,<CFSSRV - Broadcast of unknown OFN>,,<
Cause: CFSBEF was called to broadcast the EOF pointer for an OFN. This OFN
does not have an entry in the CFSOFN table.
>) ;Report error
MOVEM P1,HSHOPT(T2) ;Store broadcast value
AOS P2,HSHOP1(T2) ;Bump the transaction number
CFSULK ;Unlock CFS database
LOAD T2,STGADR,SPTH(T1) ;Get XB address
TXO T2,FILEWT ;Make token ID
LOAD T1,STRX,(T1)
TSTRMT ;Here?
RET ;Yes. Don't do anymore
CALL GNAME ;Get the name
BLCAL. (CFSBRD,<T1,T2,[.CFBEF],<.,CFSBF0>>) ;do it
RET ;And done
;Coroutine of above
CFSBF0: DMOVEM P1,CFDAT(T1) ;Stash the data
RET
SUBTTL File access token resource manager -- CFSBRD (Main broadcast routine)
;Still IFNDEF CFSDUM and still CFSBRD routines
;Routine to do a broadcast. Called by various routines to send a CI
;broadcast. Since the CI is a point-to-point bus, the broadcasr must
;be simulated by a number of point-to-point messages. The broadcast,
;therefore, is slow but since it uses virtual circuits, it is reliable.
CFSBRD::BLSUB. (<ROT,QAL,OPR,CB>) ;Lots of args!!!
SAVEQ ;Get some work ACS
MOVSI Q3,-HSTSIZ
MOVE Q1,ROT ;Get root code
MOVE Q2,QAL ;Get qualifier code
AOS CFBRDS ;Send a broadcast
CFSLOK ;Preserve the configuration
DO. ;Scan them all
SKIPLE CFSHST(Q3) ;This one up?
SKIPL T2,CFHSTS(Q3) ;Still?
IFSKP. ;If so
TRNN T2,-1 ;Is it real or dummy?
ANSKP. ;If real
CALL GVOTE ;Get a packet
NOP
DMOVEM Q1,CFROT(T1) ;Stash it
MOVE T2,OPR ;Get operator
STOR T2,CFCOD,(T1) ;And stash it
HRRZ T2,Q3 ;Host number
SKIPE T3,CB ;Want to look at it first?
CALL 0(T3) ;Yes. Give it a chance then
CALL SCASND ;Send it off
IFNSK. ;If failed
PIOFF
CALL CFSWDN ;Return the packet
PION
ENDIF.
ENDIF.
AOBJN Q3,TOP. ;Do all hosts
ENDDO.
CALLRET CFSFAL ;And done
ENDBS.
> ;IFN CFSDUM
;non-CFS dummies
IFDEF CFSDUM,<
CFSBOW::
CFSBEF::RET
> ;IFDEF CFSDUM
SUBTTL File access token resource manager -- CFSFOD (DDMP force out done)
;Here after DDMP has forced pages out.
; T1/ OFN
;Returns: +1 didn't do it
; +2 OK
IFDEF CFSDUM,<
CFSFOD::BUG.(HLT,CFSDDD,CFSSRV,SOFT,<CFSFOD called incorrectly>,,<
Cause: CFSFOD has been called by DDMP to indicate that a force out is
complete. However, as this is not a real CFS monitor, DDMP should never
have been requested to do this. This was probably caused by a bad
monitor build.
>)
> ;IFDEF CFSDUM
IFNDEF CFSDUM,< ;If real CFS
CFSFDF: TDZA T2,T2 ;Entry to force it out
CFSFOD::MOVEI T2,1 ;Normal entry from PAGEM
SAVEQ
MOVE Q2,T1 ;SAVE OFN
MOVE Q1,T2 ;[7247] Save entry flag
CFSLOK ;[7247] Lock up CFS database
LOAD T1,STRX,(Q2) ;[7247] Get STR #
LOAD T2,STGADR,SPTH(Q2) ;[7247] Get XB address
SKIPN T2 ;[7247] Is it still here?
JRST CFSFO1 ;[7247] No, all done
TXO T2,FILEWT ;[7247] Set token bit
CALL GNAME ;[7247] Get the name of the structure
CALL HSHLOK ;[7247] (T1,T2/T1,T2) Look for the token
IFNSK. ;[7247] If not here
CFSFO1: SETZRO <SPTST,SPTFR>,(Q2) ;[7247] No longer have it
JRST CFSRSK ;[7247] And done
ENDIF. ;[7247]
LOAD Q3,HSHCNT,(T1) ;[7247] Get share count
IFN. Q1 ;[7247] If normal entry
CAILE Q3,2 ;correct number of sharers?
JRST CFSFAL
ENDIF.
MOVE Q1,T1
LOAD Q3,HSHVVL,(T1) ;GET VOTE CODE
CFSULK
CALL GVOTE1 ;GET A VOTE PACKET
JRST .-1 ;It will get one soon
TMNE HSHODA,(Q1) ;Any data laying here?
SKIPA T2,HSHOPT(Q1) ;Get it
MOVE T2,OFNLEN(Q2) ;Else. Get word from SPT data base
IFN. T2 ;If something is here
MOVEM T2,HSHOPT(Q1) ;In case
MOVEM T2,CFDAT(T1) ;Store it
SETONE CFODA,(T1) ;Say we are doing it
LOAD T2,HSHTYP,(Q1) ;Get type we are giving up
MOVE T3,HSHOP1(Q1) ;Get transaction number
CAIN T2,.HTOEX ;Were we the writer?
AOS T3,HSHOP1(Q1) ;yes. Bump transaction number
MOVEM T3,CFDT1(T1) ;Indicate who we are
ELSE.
SETZM CFDT1(T1) ;No data!
ENDIF.
TMNN HSHBTF,(Q1) ;Is this a bit table?
IFSKP. ;If so
MOVE T2,Q1 ;Get hash packet
CALL SNDFRC ;Send the STR free count
ENDIF.
STOR Q3,CFUNQ,(T1) ;STORE CODE
DMOVE T2,HSHROT(Q1)
DMOVEM T2,CFROT(T1)
MOVEI T2,.CFREP
STOR T2,CFCOD,(T1)
MOVX T2,<-2>
MOVEM T2,CFTYP(T1)
MOVE Q3,T1 ;Save pointer to message
SETZRO HSHRFF,(Q1)
TMNE SPTSR,(Q2) ;[8960] Exclusive?
IFSKP. ;[8960] If not
DMOVE T1,[EXP .HTOAD,.SPSRD] ;Share it
ELSE.
SETZB T1,T2
ENDIF.
STOR T1,HSHTYP,(Q1) ;new type
STOR T2,SPTST,(Q2) ;New OFN access
TMNN OFNCSH,(Q2) ;[7247] Is the OFN cached?
IFSKP. ;[7247] Yes
MOVX T1,OFNLAC ;[7247] Get bit indicating loss of access
IORM T1,SPTH(Q2) ;[7247] Set it
AOS CFACUT ;[7247] Count this event
ENDIF. ;[7247]
LOAD T2,HSHRHN,(Q1) ;GET HOST INDEX NOW BEFORE RELEASING THE RESOURCE
SETZRO SPTFR,(Q2) ;No longer doing this
TMNN HSHCNT,(Q1) ;Any count?
CALL CFNCNT ;No
DECR HSHCNT,(Q1) ;One less unit of count
MOVE T1,Q3 ;recover message pointer
CALL SCASND ;SEND OFF VOTE
IFNSK.
PIOFF
CALL CFSWDN ;Return the buffer
PION
ENDIF.
RETSKP ;And done
;Routine to fill in STR free count in reply message
; T1/ Message to send
; T2/ hash packet
;Returns: +1 always
SNDFRC: MOVE T3,HSHCOD(T2) ;Get the OFN
LOAD T3,STRX,(T3) ;Get STR #
CALL GETFRC ;Get the current free count
MOVEM T4,CFDST0(T1) ;Save it
ADD T3,CFSSTR ;Find STR trnasaction entry
LOAD T4,HSHTYP,(T2) ;Get type we now own
CAIN T4,.HTOEX ;Exclusive?
AOSA T3,0(T3) ;Yep
MOVE T3,0(T3) ;No
MOVEM T3,CFDST1(T1) ;Save this
SETONE CFODA,(T1) ;Say we sent something
RET ;And done
> ;IFNDEF CFSDUM
SUBTTL Structure resource manager -- CFSSMT (Acquire structure resource)
;Routines to handle structures. Structure resources control the
;use of aliases as well as specify if structures are sharable.
;Acquire structure resource.
; T1/ Structure number
; T2/ type of access
; 0=) shared
; <>0=) exclusive
;Returns:
; +1 failed. Can't mount it this way
; +2 OK
;CFSSMT accomplishes two things:
; 1. It insures that the alias for this structure is
; not already in use for another structure
; 2. It insures that the name being given to this structure
; is the same as the name used by any other CFS systems.
;These guarantees are sufficient to allow the alias to be used as
;the CFS root name for this structure
;[7464]
;[7464] Note that this routine is now only called from MNTPS during system
;[7464] startup in order to register the PS structure. All other mounts
;[7464] (via MSTR) use CFSSMI to acquire the Structure Tokens.
CFSSMT::SAVEAC<Q1,Q2,Q3,P1>
STKVAR <SDBADR,STRNM,SDBOFF> ;[7464]
IFN CFSSCA,< ;Only if SCA is present
MOVEM T1,STRNM ;Save the structure number
SKIPL MYPOR1 ;Are we a dummy?
SKIPA ;Yes, force exclusive then
SKIPE T2 ;Share or exclusive?
SKIPA Q2,[.HTOEX] ;Exclusive
MOVEI Q2,.HTOAD ;Read-share
MOVE Q3,T1
CALL GNAME
EXCH Q3,T1 ;Save name
MOVE T1,STRTAB(T1) ;Get SDB address
MOVEM T1,SDBADR
MOVE T2,SDBUDB(T1) ;[7464] Get first unit
MOVE P1,UDBDSH(T2) ;[7464] Get the high-order bits
TXO P1,STRCTK ;[7464] Make it unique!
MOVE Q1,UDBDSN(T2) ;[7464] Get DSN
MOVEM T1,SDBOFF ;[7464] Remember SDBUDB offset
;..
;CFSSMT continued
;At this point
; Q1/ DSN, unswapped
; Q2/ desired access
; Q3/ Alias
; P1/ high-order serial number bits
CALL CFMNAM ;First register the name
IFNSK. ;Can't
CAIN T2,.CDVUC ;Fail due to unmatch serial number?
RETBAD(MSTX45) ;Yes, return correct error
CALLRET CFMDER ;(T2,Q2) No - analyze error
ENDIF.
CFSSM1: TLNN Q1,-1 ;[7464] See if need to swap DSN
MOVSS Q1 ;We do
CALL CFMDSN ;Now register the DSN
IFSKP. ;[7464] Ok
CAIE Q2,.HTOEX ;[7464] Got it exclusive?
IFSKP. ;[7464] If so
MOVE T1,SDBADR ;[7464] Get address of SDB
SETONE STEXL,(T1) ;[7464] Set exclusive bit
ENDIF. ;[7464]
MOVE T1,SDBOFF ;[7464] Get SDBUDB offset
ADDI T1,1 ;[7464] Get next unit
HRRZ T2,SDBUDB(T1) ;[7464] UDB address
SKIPN T2 ;[7464] Was it last?
RETSKP ;[7464] Yes all done
MOVEM T1,SDBOFF ;[7464] Save SDBUDB offset
MOVE P1,UDBDSH(T2) ;[7464] Get high order bits
TXO P1,STRCTK ;[7464] Make it unique
MOVE Q1,UDBDSN(T2) ;[7464] Get DSN
JRST CFSSM1 ;[7464] Do it for this unit
ENDIF. ;[7464]
MOVEM T2,Q1 ;Save denial reason code from CFMDSN
MOVE T1,STRNM ;Get the structure number
CALL CFSSDM ;Undo the mount
MOVE T2,Q1 ;Get denial reason code
CAIN T2,.CDVUC ;Fail due to unmatch alias name?
RETBAD(MSTX49) ;Yes, return correct error
CALLRET CFMDER ;(T2,Q2) No - analyze error
ENDSV. ;[7464]
SUBTTL Structure resource manager -- CFMNAM (Register structure name)
;Subroutine of above to register the name
; Q1/ DSN, unswapped
; Q2/ desired access
; Q3/ Alias
; P1/ high-order serial number bits
;
;Returns: +1 Failed to mount structure
; T2 contains the denial reason code
; +2 Success
CFMNAM: DO.
CALL CFSSPC ;Get a block
IFNSK. ;if none
CALL SBLOCK ;Wait here
LOOP. ;And do it again
ENDIF.
ENDDO.
MOVEM Q3,HSHROT(T1) ;Stash name
MOVX T3,STRCTN ;Bits for this
MOVEM T3,HSHQAL(T1) ;Stash it
MOVEI T2,.HTOAD ;Full share this one
STOR T2,HSHTYP,(T1) ;Store requested access
MOVE T2,Q1 ;Get low-order DSN word
XOR T2,P1 ;Make a hash of the two words
; We do this to try to improve the precision
; of the test. However, the REAL protection
; of DSN is provided in the other resource!
MOVEM T2,HSHCOD(T1) ;Save code as well
SETONE <HSHAVT,HSVUC>,(T1) ;Vote must include the code; always vote
SETZM T2 ;No auto retry
CALL CFSGET ;Try it out
RETBAD() ;No luck! Return reason for NO in T2
SKIPE T1 ;Need the block?
CALL @HSHRET(T1) ;No
RETSKP ;Done
SUBTTL Structure resource manager -- CFMDSN (Register drive serial number)
;Another subroutine of above. Register DSN
; Q1/ DSN
; Q2/ desired access
; Q3/ Alias
; P1/ high-order serial number bits
;
;Returns: +1 Failed to register drive serial number
; T2 contains the denial reason code
; +2 Success
CFMDSN: DO.
CALL CFSSPC ;Get a block
IFNSK. ;if none
CALL SBLOCK ;Wait here
LOOP. ;And do it again
ENDIF.
ENDDO.
MOVEM Q1,HSHROT(T1) ;Stash DSN
MOVEM P1,HSHQAL(T1) ;Stash high-order bits as the qualifier
STOR Q2,HSHTYP,(T1) ;Store requested access
MOVEM Q3,HSHCOD(T1) ;Save code as well
SETONE <HSHAVT,HSVUC>,(T1) ;Vote must include the code; always vote
SETZM T2 ;No auto retry
CALL CFSGET ;Try it out
RETBAD() ;No luck! Return reason for NO in T2
;[7.1012] If T1 is nonzero this means there is already a DSN token. It is
;[7.1012] likely a duplicate DSN. Note that HSHCNT was incremented by CFSGET.
;[7.1012] This will be fixed by CFSSDI later.
IFN. T1 ;[7.1075][7.1012] Need the block?
MOVE Q1,T1 ;[7.1012] Save address of unneeded block
DMOVE T1,HSHROT(T1) ;[7.1012] Get hash values
CALL HSHLOK ;[7.1012](T1,T2/T1,T2) Look up the block
BUG.(HLT,CFDGON,CFSSRV,SOFT,<CFMDSN - DSN token has disappeared>,,<
Cause: In routine CFMDSN, CFSGET has granted us access to an already existing
DSN token. But when we tried to look up token in the CFS data base, it
could not be found. Examination of the dump should try to determine
how the DSN token was released. The only way a DSN token can be
released is by dismounting the structure to which it belongs. This
should not happen because we have the device tables locked while we are
in CFMDSN.
>) ;[7.1012] Not found. wrong!
MOVE T2,HSHCOD(Q1) ;[7.1012] Get alias name
CAMN T2,HSHCOD(T1) ;[7.1012] Same as one for DSN token?
IFSKP. ;[7.1012] No
MOVE T1,HSHQAL(Q1) ;[7.1012] Get the high order DSN
HLRZ T2,HSHROT(Q1) ;[7.1012] Get the low order DSN
MOVE T3,HSHCOD(Q1) ;[7.1012] Get the structure alias
BUG.(CHK,CFDDSN,CFSSRV,HARD,<CFSSRV - Duplicate DSN detected>,<<T1,HGHDSN>,<T2,LOWDSN>,<T3,ALIAS>>,<
Cause: Routine CFMDSN was called to register a DSN for a disk mount. However,
the DSN supplied was already is use by a structure of another name.
The most likely cause of this BUGCHK is that there is more than one
drive with the same serial number available to the system.
Action: Contact Field Service and have them change the serial number on one of
the drives.
Data: HSHDSN - High order disk serial number
LOWDSN - Low order disk serial number
ALIAS - Alias name of the disk being mounted
>) ;[7.1012]
MOVE T1,Q1 ;[7.1012] Get block address back in T1
CALL @HSHRET(T1) ;[7.1012](T1/) Return the block
MOVEI T2,.CDVUC ;[7.1012] Fail due to mismatched alias names
RET ;[7.1012] Return failure
ENDIF. ;[7.1012]
CALL @HSHRET(T1) ;[7.1012](T1/) Don't need this block
ENDIF. ;[7.1012]
> ;IFN CFSSCA
RETSKP ;And done
SUBTTL Structure resource manager -- CFSSMI (Acquire structure resource)
;[7464] CFSSMI - Acquire structure resource when creating a new structure.
;Routines to handle structures. Structure resources control the
;use of aliases as well as specify if structures are sharable.
;
;This routine is called in MSTR whenever a mount is performed to acquire
;the necessary Structure Tokens. These consist of 1 Structure Name Token,
;and a DSN Token for each unit in the structure.
;
;Call with:
; T1/ Pointer to Parameter area in Monitor (set by MSTR)
; T2/ type of access
; 0=) shared
; <>0=) exclusive
; Q3/ Alias
;Returns:
; +1 failed. Can't mount it this way
; +2 OK
;
;CFSSMI accomplishes the same things as CFSSMT but is called at structure
; creation and we do not have a SDB
CFSSMI::
IFE CFSSCA,<RETSKP>
IFN CFSSCA,< ;Only if SCA is present
SAVEAC<Q1,Q2,Q3,P1>
STKVAR <UNIADR,AOBPTR,FTIM,BLADR>
MOVEM T1,BLADR ;Save the parameter block address
SETZM FTIM ;First time
SKIPL MYPOR1 ;Are we a dummy?
SKIPA ;Yes, force exclusive then
SKIPE T2 ;Share or exclusive?
SKIPA Q2,[.HTOEX] ;Exclusive
MOVEI Q2,.HTOAD ;Read-share
MOVEI T2,.MSISU(T1) ;Get address of first unit
HRRZ T1,.MSIUNU(T1) ;Get number of units
MOVN T1,T1 ;Negate it
MOVSI T1,(T1) ;Form AOBJN pointer
CFSSI1: MOVEM T1,AOBPTR ;Save it
MOVEM T2,UNIADR ;Save adress of unit
MOVE T3,.MSIUN(T2) ;Get Unit
DMOVE T1,.MSICH(T2) ;Get Chan ,Kont
CALL CHKCKU ;(T1,T2,T3/T1)Get UDB address
RET ;Erreur, code in T1
MOVE P1,UDBDSH(T1) ;Get high order bits
TXO P1,STRCTK ;Make it unique
MOVE Q1,UDBDSN(T1) ;Get DSN
SKIPE FTIM ;Is it first time?
IFSKP. ;Yes
SETOM FTIM ;There is only one first time
CALL CFMNAM ;First register the name
IFNSK. ;Can't
CAIN T2,.CDVUC ;Fail due to unmatch serial number?
RETBAD(MSTX45) ;Yes, return correct error
CALLRET CFMDER ;(T2,Q2) No - analyze error
ENDIF.
ENDIF.
TLNN Q1,-1 ;Do we need to swap SN?
MOVSS Q1 ;Yes
CALL CFMDSN ;Now register DSN
IFSKP. ;done
MOVE T2,UNIADR ;Get unit address
MOVE T1,AOBPTR ;get AOBJN pointer
ADDI T2,.MSTNO ;Get next unit address
AOBJN T1,CFSSI1 ;Go do next unit
RETSKP ;All done
ENDIF.
MOVEM T2,Q1 ;Save denial reason code from CFMDSN
MOVE T1,BLADR ;Get parameter block address
CALL CFSSDI ;(T1,Q3/)Undo the mount
MOVE T2,Q1 ;Get denial reason code
CAIN T2,.CDVUC ;Fail due to unmatch alias name?
RETBAD(MSTX49) ;Yes, return correct error
CALLRET CFMDER ;(T2,Q2) No - analyze error
ENDSV.
> ;IFN CFSSCA
SUBTTL Structure resource manager -- CFSSUG (Upgrade or downgrade mount)
;Routine to upgrade or downgrade a CFS mount resource.
; T1/ Structure number
; T2/ New access needed
; Same as for CFSSMT
;
;Returns: +1 Can't do it
; +2 Done
CFSSUG::
IFN CFSSCA,< ;Only if SCA is present
SAVEQ ;Get some work regs
STKVAR <SDBOFF> ;[7464] For SDBUDB offset
SKIPL MYPOR1 ;Are we a real node?
RETBAD(MSTX46) ;No. Can't do this function then
SKIPE T2 ;Share or exclusive?
SKIPA Q1,[.HTOEX] ;Exclusive
MOVEI Q1,.HTOAD ;Share
MOVE T1,STRTAB(T1) ;Get SDB
CFSSU1: MOVE T2,SDBUDB(T1) ;[7464] Get SDB address
MOVEM T1,SDBOFF ;[7464] Save SDB offset
MOVE T1,UDBDSN(T2) ;[7464] Get DSN
MOVE T2,UDBDSH(T2) ;[7464] Get the high-order bits
TLNN T1,-1
MOVSS T1
TXO T2,STRCTK
CFSLOK
CALL HSHLOK ;Look it up
BUG.(HLT,CFSSUF,CFSSRV,SOFT,<CFSSUG - Could not find entry to upgrade>,,<
Cause: A request was made to change the mount type of a structure, and the CFS
data base has no record of the structure being mounted.
>)
LOAD T2,HSHTYP,(T1) ;Get current type
CAMN T2,Q1 ;The same?
IFSKP. ;[7464] No
MOVE Q2,T1 ;Save entry
DMOVE T1,HSHROT(T1) ;Get codes
MOVE T3,Q1 ;Access
CALL CFSUGA ;Do it
IFNSK.
MOVE Q2,Q1 ;Can't upgrade - get desired access
CALLRET CFMDER ;(T2,Q2) Return appropriate error
ENDIF.
DECR HSHCNT,(Q2) ;[7464] Don't need this
ELSE. ;[7464] Type is the same
CFSULK ;[7464] Unlock because CFSUGA does it too
ENDIF. ;[7464]
MOVE T1,SDBOFF ;[7464] Get SDBUDB offset
ADDI T1,1 ;[7464] Get next unit
HRRZ T2,SDBUDB(T1) ;[7464] UDB address
SKIPN T2 ;[7464] Was it last?
RETSKP ;[7464] Yes, done
JRST CFSSU1 ;[7464] Do next unit
> ;IFN CFSSCA
RETSKP ;And done
ENDSV. ;[7464]
SUBTTL Structure resource manager -- CFMDER (Mount/Dismount error)
; This routine is used by CFSSMT and CFSSUG upon failure.
; It will convert the denial reason code (returned from the failed vote)
; into a meaningful TOPS-20 error code and RETBAD with it.
;
; Expects: T2/ Denial reason code
; Q2/ Desired access
CFMDER: SKIPN T2 ;[7330] Did we receive an expected error code?
JRST CFMDE1 ;[7330] No - invalid error code
SKIPG T2 ;[7330] Did the mount fail on this system?
RETBAD(MSTX50) ;[7330] Yes, so say so
CAIE T2,.CDOCT ;Fail because it is owned on another system?
RETBAD(MSTX44) ;No, not a special error worth calling out.
CAIE Q2,.HTOEX ;Did we want exclusive?
RETBAD(MSTX47) ;No. Failed because another system had .HTOEX
RETBAD(MSTX48) ;Yes. Failed because another system had .HTOAD
CFMDE1: BUG.(HLT,CFSTUC,CFSSRV,SOFT,<CFSSRV - Unexpected error encountered during structure operation>,<<T2,CODE>>,<
Cause: A structure mount or dismount failed and generated an unexpected or
illegal error code of zero. This should never happen.
Data: CODE - Bogus error code
>) ;[7330]
SUBTTL Structure resource manager -- CFSSDM (Release mount resource)
;Routine to undo the MOUNT entry
; T1/ STRUCTURE number
;Returns: +1 always
CFSSDM::
IFE CFSSCA,<RET>
IFN CFSSCA,< ;Only if SCA is present
SAVEAC <Q1,Q2,Q3,P1> ;Get some regs to work with
STKVAR <SDBOFF> ;[7464] SDBUDB offset
MOVE Q3,T1 ;Save STR number
CALL GNAME
EXCH T1,Q3 ;Save name, get str num back
MOVE T1,STRTAB(T1) ;Get SDB
MOVE T2,SDBUDB(T1) ;[7464] Get UDB of first unit
MOVE Q1,UDBDSN(T2) ;[7464] Get serial number
MOVE P1,UDBDSH(T2) ;[7464] Get the high-order bits
MOVEM T1,SDBOFF ;[7464] Save SDBUDB Offset
TXO P1,STRCTK
TLNN Q1,-1 ;Something in the LH?
MOVSS Q1 ;No
;Now have:
; Q1/ DSN
; Q3/ name
; P1/ high-order DSN bits
CFSLOK ;Lock up the data base
MOVE T1,Q3 ;Copy the name
MOVX T2,STRCTN ;Get proper qualifier
CALL HSHLOK ;Look 'er up
SKIPA ;If not here, forget it
CALL CFSRMV ;Remove it
MOVE T1,Q1 ;Get DSN
MOVE T2,P1 ;Get qualifier
CFSSD1: CALL HSHLOK ;[7464] (T1,T2/T1,T2)Look it up
SKIPA
CALL CFSRMV ;And remove it
MOVE T1,SDBOFF ;[7464] Get SDBUDB offset
ADDI T1,1 ;[7464] Get next unit
HRRZ T2,SDBUDB(T1) ;[7464] UDB address
SKIPN T2 ;[7464] Was it last ?
CALLRET CFSFAL ;[7464] yes All done
MOVEM T1,SDBOFF ;[7464] Save SDB offset
MOVE T1,UDBDSN(T2) ;[7464] Get serial number
MOVE T2,UDBDSH(T2) ;[7464] Get high order bits
TXO T2,STRCTK ;[7464] Make it unique
TLNN T1,-1 ;[7464] Something in the LH?
MOVSS T1 ;[7464] No
JRST CFSSD1 ;[7464] Do it for next unit
ENDSV. ;[7464]
> ;IFN CFSSCA
SUBTTL Structure resource manager -- CFSSDI (Release mount resource)
;[7464] CFSSDI - Routine to undo the MOUNT entry when we do not have SDB yet
;(in case of structure creation)
;
;Call with:
; T1/ User block address in monitor space (from MSTR)
; Q3/ Alias
;Returns: +1 always
CFSSDI::
IFE CFSSCA,<RET>
IFN CFSSCA,< ;Only if SCA is present
SAVEAC <Q1,Q2,Q3,P1> ;Get some regs to work with
STKVAR <UNIADR,AOBPTR,FTIM>
SETZM FTIM ;It is first time
MOVEI T2,.MSISU(T1) ;Get address of first unit
HRRZ T1,.MSIUNU(T1) ;Get number of units
MOVN T1,T1 ;Negate it
MOVSI T1,(T1) ;Form AOBJN pointer
CFSLOK ;Lock up CFS database
CFSDI1: MOVEM T1,AOBPTR ;Save it
MOVEM T2,UNIADR ;Save Unit address
MOVE T3,.MSIUN(T2) ;Get Unit nb
DMOVE T1,.MSICH(T2) ;Get Chan,Kont
CALL CHKCKU ;(T1,T2,T3/T1) Get UDB address
RET ;Failed erreur code in T1
MOVE Q1,UDBDSN(T1) ;Get DSN
MOVE P1,UDBDSH(T1) ;Get high order bits
TXO P1,STRCTK ;Make it unique
TLNN Q1,-1 ;Do we have to swap?
MOVSS Q1 ;Yes
SKIPE FTIM ;Is it first time?
IFSKP. ;Yes
SETOM FTIM ;No more first time
MOVE T1,Q3 ;Get Alias
MOVX T2,STRCTN ;Get proper qualifier
CALL HSHLOK ;(T1,T2/T1,T2)Look it up
SKIPA ;not there
CALL CFSRMV ;(T1/)Remove it
ENDIF.
MOVE T1,Q1 ;Get DSN
MOVE T2,P1 ;Get qualifier
CALL HSHLOK ;(T1,T2/T1,T2)Look it up
IFSKP. ;[7.1012] If we found it
DECR HSHCNT,(T1) ;[7.1012] Decrement hash count
OPSTR <SKIPG>,HSHCNT,(T1) ;[7.1012] Still shared?
CALL CFSRMV ;[7.1012](T1/) No, remove it
ENDIF. ;[7.1012]
MOVE T2,UNIADR ;Get address of unit
MOVE T1,AOBPTR ;Get AOBJN pointer
ADDI T2,.MSTNO ;Get address of next unit
AOBJN T1,CFSDI1 ;Do it for next unit
CALLRET CFSFAL ;All done
ENDSV.
> ;IFN CFSSCA
SUBTTL Structure resource manager -- STRVER (Structure verify)
;Routine called during "CI joining" to reverify any structure resource.
;This is done in the event one or more nodes have been off of the CI
;and mounted structures without benefit of the voting operation.
;The reverification simply votes on the current state of the structure
;mount resources.
STRVER:
IFE CFSSCA,<RET> ;NOTHING TO DO FOR NON-CFS SYSTEMS
IFN CFSSCA,<
SAVEP ;Get some regs to use
MOVSI P1,-STRN ;Scan the table
DO.
SKIPN P2,STRTAB(P1) ;Anybody here?
IFSKP. ;If so
MOVEI T1,0(P1) ;Get STR number
CALL GNAME ;Get its name
MOVX T2,STRCTN ;Look up resource
CALL HSHLOK
ANSKP. ;If we have it registered...
CALL STRVVT ;Do vote
MOVE P2,SDBUDB(P2) ;Get UDB address
MOVE T2,UDBDSH(P2) ;Get high order serial number
MOVE T1,UDBDSN(P2) ;Get low order
TXO T2,STRCTK ;Make it unique
TLNN T1,-1
MOVSS T1 ;Get DSN in right order
CALL HSHLOK ;Look this up too
ANSKP. ;If here
CALL STRVVT ;Do vote
ENDIF. ;Done with that one
AOBJN P1,TOP. ;Do all entries
ENDDO.
RET ;Done
;Local routine of STRVER to do upgrading.
; T1/ resource block
; uses P3 (temp of STRVER)
STRVVT: MOVE P3,T1 ;Save block
DMOVE T1,HSHROT(T1) ;Get name
LOAD T3,HSHTYP,(P3) ;Get current access
CFSLOK
CALL CFSUGZ ;do it
BUG.(HLT,CFSVFL,CFSSRV,SOFT,<CFSSRV - Structure verify failed>,,<
Cause: CFS could not verify an existing structure resource during the join
operation. This probably means there is a structure naming conflict.
There is one known scenario for this BUGHLT. If the CFS joining
process did not complete properly, then this system may have acquired
some of the resources exclusively when they were also held on other
nodes. By the time STRVVT is called to verify the structure access,
all the CFS connections have completed. So, the verification of
exclusive access has failed now that all the other cluster systems are
voted with.
Action: Insure that there is no naming conflict or drive serial number conflict
with the structures. Insure that the BS: and PS: are not mounted
exclusively by any other system in the cluster. If the structures all
appear to be in order, submit an SPR with the dump and a copy of
MONITR.EXE.
>)
DECR HSHCNT,(P3) ;Don't need this count
RET ;Done
> ;IFN CFSSCA
;job 0 routine called from CHKR for stuff
CFSJ0:: JE SCVER,,R ;If no bit set, all done
SETZRO SCVER ;no longer needed
CALLRET STRVER ;Do it
SUBTTL File enqueue resource manager -- CFSENQ (Get ENQ resource)
;Routines to obtain and release ENQ lock on a file. This code is the
;ENQ "detector" that prevents two or more version 6.1 CFS nodes from
;using ENQ on the same file!
;
;As of version 7.0, this routine creates the ENQ token with shared
;access for 7.0 ENQ implementations and with exclusive access for 6.1
;ENQ implementations.
;
; T1/ OFN
;
; CALL CFSENQ ;(T1/)
;
;Returns +1: Failed, another node has the token
; +2: Success
IFDEF CFSDUM,< ;If a reduced CFS
CFSENQ::RETSKP ;Succeed
> ;IFDEF CFSDUM
IFNDEF CFSDUM,<
CFSENQ::SAVEQ
STKVAR <OFNENQ> ;[7348]
MOVEM T1,OFNENQ ;[7348] Save the OFN
LOAD Q3,STRX,(T1)
CALL ENQSET ;Set up args
JRST RSKP ;Local. All set
DMOVE Q1,T1
DO.
CALL CFSSPC ;Get some space
IFNSK. ;If failed
CALL SBLOCK ;Wait a bit
LOOP.
ENDIF.
ENDDO.
DMOVEM Q1,HSHROT(T1) ;Stash it
MOVEI T2,.HTOEX ;Exclusive please
IFN CLEQIN,< ;[7.1072] If cluster ENQ code present
MOVE T3,ENQWRD ;[7.1072] Get ENQ word for process
TXNE T3,EQ%ENA ;[7.1072] Did process enable cluster wide ENQ?
MOVEI T2,.HTOAD ;[7.1072] Yes, so access is shared
> ;[7.1072]
STOR T2,HSHTYP,(T1) ;Ask for it
SETONE HSHLCL,(T1) ;But it is local exclusive
SETZM T2 ;No retry
MOVE T3,STRTAB(Q3) ;Get SDB
LOAD T3,STEXL,(T3) ;Get shared/exclusive indicator
CALL @[ IFIW!CFSGET
IFIW!CFSGTL](T3)
RETBAD() ;Nope. Someone else has it
SKIPE T1
CALL @HSHRET(T1) ;If didn't need it
CFSLOK ;[7348] Lock the database
DMOVE T1,Q1 ;[7348] Get root and qualifier
CALL HSHLOK ;[7348] (T1,T2/T1,T2)Find the entry
BUG.(HLT,CFEQHF,CFSSRV,SOFT,<ENQ token not found>,,<
Cause: An ENQ token was just created and one already existed so the block
which was passed has been released. Now, we are attempting to find the
original block and this has failed. To diagnose this problem, look in
CFS free space to try to find the remains of the original block. Try
to determine how the block could have been released even though this
routine acquired it.
>) ;[7348] Error!
MOVE T2,OFNENQ ;[7348] Get the OFN for this ENQ
MOVEM T2,HSHCOD(T1) ;[7348] Put it in the token
JRST CFSRSK ;[7348] Unlock database and return success
ENDSV. ;[7348] End of STKVAR
> ;IFNDEF CFSDUM
SUBTTL File enqueue resource manager -- CFSDEQ (Release ENQ resource)
;Release ENQ resource
; T1/ OFN
;Returns: +1 always
IFDEF CFSDUM,<
CFSDEQ::RET
> ;IFDEF CFSDUM
IFNDEF CFSDUM,< ;If real CFS
CFSDEQ::CALL ENQSET ;Get args
RET ;Local structure
CALL CFSNDO ;undo it
NOP ;??
RET ;And done
;Utility to set up args for ENQ/DEQ stuff
; T1/ OFN
ENQSET: STKVAR <SAVOFN> ;[7315] A place to save the OFN
TMNN OFNDMO,SPTH(T1) ;[7315] Is this OFN dismounted?
IFSKP. ;[7315] Yes
MOVEM T1,SAVOFN ;[7315] Save this for later
HRLZS T1 ;[7315] Form OFN,,0 for call
CALL OFNJFD ;[7315] (T1/T1)Convert OFN into JFN
BUG.(HLT,CFEQSF,CFSSRV,SOFT,<CFSSRV - Could not convert OFN to JFN>,,<
Cause: ENQSET was called to set up the root and qualifier for the ENQ token
for a certain OFN. This OFN was dismounted so the routine must look in
the JFN block for the structure name because the STRTAB entry is zero.
However, the conversion from OFN to JFN failed. To diagnose this
problem, investigate the dump to try to determine why the call to
OFNJFN failed.
>) ;[7315] Error!
HLRZS T1 ;[7315] Position the JFN correctly
IMULI T1,MLJFN ;[7315] Convert into internal offset
LOAD T1,FLDSB,(T1) ;[7315] Get the pointer to the device string
CALL ASCSIX ;[7315] (T1/T1,T2)Convert to sixbit
NOP ;[7315] This should not fail!
MOVE T2,SAVOFN ;[7315] Get back saved OFN
LOAD T2,STGADR,SPTH(T2) ;[7315] Get XB address
ELSE. ;[7315] OFN is not dismounted
LOAD T2,STGADR,SPTH(T1) ;[7315] Get XB address
LOAD T1,STRX,(T1) ;[7315] Get structure number
CALL GNAME ;[7315] (T1/T1)Get the structure name
ENDIF. ;[7315]
TXO T2,FILEEQ ;Ask for this resource
RETSKP ;And done
ENDSV. ;[7315]
> ;IFNDEF CFSDUM
SUBTTL ENQ Lock resource manager -- CFEQLK (Lock ENQ database)
IFN CLEQIN,< ;[7.1072] Assemble only if cluster ENQ desired
;[7.1072] CFEQLK - Lock the ENQ database
;Routine to obtain the ENQ Database Lock Token. This routine is called
;from ENQ.MAC to lock the ENQ database. Since this is an exclusive
;token, this implies that there is only one ENQ activity ongoing in
;the cluster at a time. The process is CRSKED while the Lock is held.
;
;Must be called NOINT.
;
; CALL CFEQLK ;()
;
;Returns +1: Always when the ENQ Database Lock is obtained.
; Process is CSKED upon return.
;
; Preserves ACs T1 - T4.
CFEQLK::SAVET ;Preseve the temps
CSKED ;Be CSKED while lock is owned
CFSLOK ;Prevent CFS interruptions
MOVX T1,EQLROT ;Get root
MOVX T2,EQLQAL ;Get qualifier
CALL HSHLOK ;(T1,T2/T1,T2) See if we have it
JRST CFEQL1 ;No so we need to vote for it
JN <HSHWVT,HSHCNT>,(T1),CFEQL1 ;If in use or voting already, do vote
INCR HSHCNT,(T1) ;Its on the system but not in use - get it
MOVE T3,FORKX
STOR T3,HSHFRK,(T1) ;Store new owner
MOVE T3,TODCLK ;Get now
MOVEM T3,HSHTIM(T1) ;Store in resource block
CALLRET CFSFAL ;Succeed but don't update fairness timer
;Here if we need to vote for the Lock
CFEQL1: CFSULK ;Unlock CFS database while voting
DO.
CALL CFSSPC ;(/T1) Get a short request block
IFNSK. ;If failed
CALL SBLOCK ;() Release some and wait awhile
LOOP. ;Try again
ENDIF.
ENDDO.
;Fill in the request block and ask for the resource
MOVX T2,EQLROT ;Get root
MOVEM T2,HSHROT(T1) ;Store in resource block
MOVX T2,EQLQAL ;Get qualifier
MOVEM T2,HSHQAL(T1) ;Store in resource block
MOVEI T2,.HTOEX ;This resource is always exclusive
STOR T2,HSHTYP,(T1) ;Store in resource block
SETZM HSHCOD(T1) ;No unique code required
MOVE T3,TODCLK ;Get the time
ADDI T3,EQFTIM ;Add fairness value to it
MOVEM T3,HSHFCT(T1) ;Stash it as the minimum hold time
CALL CFSGET ;(T1,T2/T1,T2) Get the resource
CALL ILLGET ;This retries till successful so crash if failed
SKIPE T1 ;We now have the lock! Did our block get used?
CALL @HSHRET(T1) ;No, so return it
RET ;Return successful
SUBTTL ENQ Lock resource manager -- CFEQUL (Unlock ENQ database)
;[7.1072] CFEQUL - Unlock the ENQ database
;Routine to release the ENQ Database Lock Token. This routine is
;called from ENQ.MAC to unlock the ENQ database.
;
;Always called NOINT and CSKED.
;
; CALL CFEQUL ;()
;
;Returns +1: Always with the database lock unlocked.
; An ECSKED is done to undo the CSKED done in CFEQLK.
;
; Preserves ACs T1 - T4.
CFEQUL::SAVET ;Preserve the temps
MOVX T1,EQLROT ;Get root
MOVX T2,EQLQAL ;Get qualifier
CALL CFSNDO ;(T1,T2/) Release the Lock
IFNSK. ;If can't then it wasn't locked!
BUG.(CHK,ENQLNL,CFSSRV,SOFT,<CFSSRV - ENQ Database Lock not locked>,,<
Cause: CFEQUL was called to unlock the ENQ Database Lock, but the Lock
was found not to be locked.
Action: If this problem is reproducible, set this BUGCHK dumpable and submit an
SPR along with the dump and instructions on reproducing the problem.
>)
RET ;Issue warning and quit
ENDIF.
ECSKED ;Undo CSKED done when lock was acquired
RET ;Return success
> ;[7.1072] End of IFN CLEQIN
SUBTTL Miscellaneous Interfaces -- FILRST (Reset all files at startup)
;Routine called at system start-up to reset all file states to unowned.
;This is used so that we can mount PS: after reading it.
FILRST::
REPEAT 0,< ;Don't need this while PS: are not shared
SAVEAC <P1> ;Get a work reg
IFNDEF CFSDUM,< ;Only if real CFS
;
; NOTE: IT MIGHT BE USEFUL TO ONLY SEARCH THE OFNS POINTED TO BY THE HASH
; TABLE BUT THIS CODE IS DONE VERY INFREQUENTLY SO IT DOESN'T REALLY
; MATTER NOW. TAM 28-JAN-85
;
MOVEI P1,1 ;Start with first OFN
SETOM DDPFRK ;Pretend we are DDMP
DO. ;Loop over them all
SKIPN SPTH(P1) ;This one in use?
IFSKP. ;If so.
SETONE SPTFR,(P1) ;Say we need it flushed
CALL DDOCFS ;Do it
ANNSK. ;But if it failed
MOVEI T1,1 ;Do a short dismiss
DISMS ;""
JRST TOP.
ENDIF.
CAIGE P1,NOFN ;All done?
AOJA P1,TOP. ;No. DO them all
ENDDO. ;All done
SETZM DDPFRK ;No longer DDMP
> ;IFNDEF CFSDUM
> ;REPEAT 0
RET ;""
SUBTTL Miscellaneous Interfaces -- CFSERR (Illegal configuration)
;Here when an illegal CFS confiugration occurs
CFSERR::BUG.(HLT,CFSICN,CFSSRV,SOFT,<CFSSRV - Illegal configuration>,,<
Cause: This system has detected an illegal configuration. There may be too
many nodes in the network. The caller of this routine should be
examined for more details.
>)
SUBTTL Miscellaneous Interfaces -- CFRDSN (Read drive serial number)
;Routine called from PHYSIO when a pack that is part of a mounted
;structure is moved to a new drive. The events that cause this are:
;1) operator reassignment (moving the pack), or 2) shadow-set failure.
;This routine handles the case of a pack being moved to a previously
;unused drive; it is called so that the CFS resource may be "renamed".
;It does not handle the case of two packs swapped between their drives.
;This unsupported case seems useless and is very hard to support without
;serious races.
;ACCEPTS: T1/ new UDB
; T2/ previous UDB for this
;RETURNS: +1
CFRDSN::
IFE CFSSCA,<RET> ;If no SCA, done
IFN CFSSCA,< ;If an SCA
EA.ENT ;Need to be extended
SAVEQ ;[7464] Save some work registers
STKVAR <NUDB,OUDB>
SETOM Q1 ;Indicate we entered at CFRDSN
MOVEM T1,NUDB ;Save the arguments
MOVEM T2,OUDB
JRST CFDSN1 ;Continue at common code
SUBTTL Miscellaneous Interfaces -- CFSDSN (Swap drive serial number)
;Routine called from PHYSIO when the drive serial number of a unit
;changes. This can happen when the HDA of a DSA disk (RA60/RA81) is
;changed while the system is still running.
;
;PHYSIO will provide the address of the UDB (with the new serial number
;stored in it) and the old drive serial number. This routine will proceed
;to unlink the old resource blocks, adjust the DSN, and link this new block
;into its appropriate place in the hash table. Conceptually, the old blocks
;are removed and replaced by the new ones. But in effect, the old blocks
;are never actually destroyed, just updated and relinked.
;
;This routine only handles the case of a drive being assigned a new DSN and
;this new DSN does not already have a CFS resource which describes it. If
;a CFS resource exists for the new DSN, and it is for a different structure
;name, then a CFSRNM BUGHLT will result. This case is not only unsupported
;but clearly illegal.
;
;Expects: T1/ high-order word of old DSN
; T2/ low-order word of old DSN
; P3/ UDB updated with new drive serial number
;Returns: +1 always
CFSDSN::
IFE CFSSCA,<RET> ;If no SCA, done
IFN CFSSCA,< ;If an SCA
EA.ENT ;Need to be extended
SAVEQ ;[7464] Save some work registers
STKVAR <NUDB,HDSN,LDSN>
SETZM Q1 ;Indicate we entered at CFSDSN
MOVEM P3,NUDB ;Save arguments
MOVEM T1,HDSN
MOVEM T2,LDSN
; JRST CFDSN1 ;Continue at common code
;..
;This is common code used by both CFRDSN and CFSDSN.
;..
CFDSN1: MOVE T1,NUDB ;Get new UDB
MOVE T3,UDBSTR(T1) ;Get structure "back pointer"
SETZM Q3 ;[7464] Assume that this is the 1st unit
TLNE T3,-1 ;[7464] Is this the first unit?
SETOM Q3 ;[7464] No. So remember this.
;[7464] Rename the CFS resource.
;[7464] The DSN Token will be unlinked, changed, and relinked.
;[7464] The Name Token will have HSHCOD changed if the first unit is the
;[7464] one which is affected.
MOVE T2,UDBDSH(T1) ;Get high-order bits for new DSN from new UDB
MOVE T1,UDBDSN(T1) ;Get low-order bits
TXO T2,STRCTK ;Prepare to look up resource based on new DSN
TLNN T1,-1
MOVSS T1
CALL HSHLOK ;(T1,T2/T1,T2) See if it is around
IFSKP. ;If so, this could be bad
MOVE T2,NUDB ;Recover the UDB
HRRZ T2,UDBSTR(T2) ;Get SDB pointer
CALL GNAME2 ;(T2/T2) Get name of this structure
CAMN T2,HSHCOD(T1) ;Same as the resources name?
RET ;Yes. Nothing to do then.
;If we are here, it is likely the system will crash with a CFSRNM BUGHLT.
;The most likely reason for the crash is the unsupported case of two packs
;swapped between their drives. This could also indicate another unsupported
;case where a drive is given a new HDA (and thus a new drive serial number)
;and this DSN is already described by a CFS resource for structure of a
;different name.
ENDIF.
SKIPL Q1 ;Did we move the pack to a new drive?
IFSKP. ;Yes
MOVE T2,OUDB ;Recover the old UDB address
MOVE T1,UDBDSN(T2) ;Get DSN
MOVE T2,UDBDSH(T2) ;Get the high-order bits
ELSE. ;No, drive received a new serial number
MOVE T1,LDSN ;Get the low-order bits of the old DSN
MOVE T2,HDSN ;Get the high-order bits of the old DSN
ENDIF.
TLNN T1,-1 ;Anything in the LH?
MOVSS T1 ;No
TXO T2,STRCTK ;Qualifier
CALL HSHLOK ;(T1,T2/T1,T2) Look 'er up
RET ;Not here. Nothing more to do
;Found the entry. Dequeue it and rename it.
CALL HSHULN ;(T1) Remove it
MOVE T3,NUDB ;Get new UDB
DMOVE T3,UDBDSH(T3) ;Get the new DSN
TLNN T4,-1 ;LH OK?
MOVSS T4 ;No.
MOVEM T4,HSHROT(T1) ;New name
TXO T3,STRCTK ;Form high-order DSN as qualifier
MOVEM T3,HSHQAL(T1)
MOVEM T1,Q2 ;Save pointer to resource block
DMOVE T1,HSHROT(T1) ;Get name
CALL HSHLOK ;(T1,T2/T1,T2) Look up new name
SKIPA T2,Q2 ;If not here, good, so get packet address
BUG.(HLT,CFSRNM,CFSSRV,SOFT,<CFRDSN - Could not rename DSN entry>,,<
Cause: A pack of a mounted structure has been moved to a new unit and the new
CFS mount resource already exists for the new drive. Or, a drive on
which there is a pack of a mounted structure has been given a new drive
serial number and the new CFS mount resource already exists for the new
drive. This indicates either the CFS database is wrong, or PHYSIO's
database is wrong.
>)
MOVEM T2,HSHLNK(T1) ;Enqueue it
MOVEM T1,HSHBKP(T2) ;And point backwards as well
SETZM HSHLNK(T2) ;Clear our link
IFE. Q3 ;[7464] If this is first unit, fix Name Token
MOVE T1,HSHCOD(T2) ;Get the STRUCTURE name
MOVX T2,STRCTN ;Look up the name
CALL HSHLOK ;(T1,T2/T1,T2) Do it
IFSKP. ;We should have found the resource!!
MOVE T2,NUDB ;Get the new UDB
MOVE T3,UDBDSN(T2) ;Get the low order DSN
MOVE T4,UDBDSH(T2) ;Get the high order DSN
TXO T4,STRCTK ;Make high order word unique
XOR T3,T4 ;Make the hash code
MOVEM T3,HSHCOD(T1) ;Stash in the packet as the code
ENDIF.
ENDIF. ;[7464]
RET ;And done
ENDSV.
> ;IFN CFSSCA
SUBTTL Miscellaneous Interfaces -- CFCBRD (Broadcast system cease)
;CFCBRD - Cease broadcast, called by MEXEC during the shutdown sequence.
;This routine broadcasts cease, cease canceled, and timesharing is over
;so other systems can take action with regards to structures being accessed
;through the MSCP server.
; CALL CFCBRD ;(/)
; RETURN +1: No other systems out there
; +2: Sent the message
;
;USES: T1,T2/ ASCIZ OF OUR NODE NAME
;******
;FOR A MORE COMPLETE DESCRIPTION OF THE "CLUSTER CEASE" PROCESSING, SEE THE
;LARGE COMMENT PRECEDING ROUTINE CFCEAS.
;******
CFCBRD::
IFDEF CFSDUM,<RET> ;If reduced CFS, just return
IFNDEF CFSDUM,< ;Full CFS so do routine
SKIPN CFSHCT ;Anybody else out there?
RET ;No, nothing else to do
DMOVE T1,OURNAM ;Get our node name
BLCAL. (CFSBRD,<T1,T2,[.CFSHT],<.,CFSHCO>>) ;Do the broadcast
RETSKP ;Done
;Coroutine of above. Used to stash the node number and shutdown time.
CFSHCO: SAVEAC <T1,T2> ;Do not trash anything
MOVE T2,T1 ;Save vote packet
CALL CFSPRT ;(/T1) Get our local port number
MOVEM T1,CFDAT(T2) ;Store it in the vote packet
MOVE T1,HSYST1 ;GET CEASE TIME
MOVEM T1,CFDT1(T2) ;Store time in the vote packet
;It is placed in the transaction number word
RET ;Return
> ;End of IFNDEF CFSDUM
SUBTTL Miscellaneous Interfaces -- CFSDMP (Force cluster dump)
;[7.1021] CFSDMP - Force a cluster dump
;
;This routine can be called anytime a cluster dump is desired. It will
;attempt to connect to the cluster dump listener of every TOPS-20 node
;which is answering REQUEST-IDs on the CI. If a connection is made, then
;word CLDWRD will be set non-zero on that node. Once we have completed our
;attempts at connecting to all the cluster dump listeners, this node will
;crash with a CFCLDP BUGHLT. When the other nodes see this node go down,
;then they will also crash with a KLPDMP BUGHLT.
;
;Note that this has been designed so that a "DEP TEN 67=1;QUIT" issued at
;the PARser will perform a cluster dump. Or, a "DEP TEN 66=1;QUIT" command
;can be given at each system, and then a "Jump 71" can be issued (this will
;result in a KPALVH on one system, and a KLPDMP on the others). This second
;method should be used if there is any doubt about the ability of this
;system to make connections to the remote cluster dump listeners.
;
; Accepts no arguments
;
; CALL CFSDMP
; - or -
; PAR> DEP TEN 67=1;QUIT
;
;Never returns. Always issues a CFCLDP BUGHLT.
CFSDMP::MOVEM P,DMPSVP ;Save incoming stack
MOVE P,DMPSTK ;Get local dump stack
XJRST [MSEC1,,.+1] ;[7.1033] Enter section 1
PIOFF ;Own the system for awhile
SAVEQ ;Save some work registers
MOVSI Q1,-C%SBLL ;Loop for all the nodes
DO.
XCT KEPALV ;Update keep alive counter
HRRZ T1,Q1 ;Get the current node
CAMN T1,MYPOR4 ;Is this our node?
JRST CFSDM1 ;Yes, skip it
CALL PTHSTS ;(T1/T1,T2) What is path status to node
EXIT. ;Our port is not running - quit
TXNN T2,UDB%WA+UDB%WB ;No-response on both wires?
JRST CFSDM1 ;Yes, skip it
TXNE T2,UDB%MA ;No, is node in maintenance mode?
JRST CFSDM1 ;Yes, skip it
SKIPN SBLIST(Q1) ;No, have we created a system block yet?
JRST CFSDM1 ;No, skip it
HRRZ T2,Q1 ;Get the node number again
CALL ISIT20 ;(T2/) Is this a TOPS-20 system?
JRST CFSDM1 ;No, skip it
;Here if we found a node that needs to have a dump taken
HRRZ T1,Q1 ;Get node number
MOVEM T1,Q2 ;Save it in case error occurs
CSKED ;Make us more important
PION ;Turn on interrupts again
BLCAL. (SC.CON,<<.,LISDMP>,<.,LISDMP>,T1,[0],[0],<.,CFSINT>,T1,[0],[0],[0]>) ;[7.1190] Do connect
BUG.(INF,CFCDCF,CFSSRV,SOFT,<CFSSRV - Cluster dump connect attempt failed>,<<Q2,NODE>,<T1,ERR>>,<
Cause: An attempt to connect to the cluster dump listener on another node has
failed. This means that, most likely, when this node crashes, the
remote node will not. Chances are, this BUGINF will not appear on the
CTY or in ERROR.SYS but it should be queued in the dump.
Action: If this problem is reproducible, set this BUGCHK dumpable and submit an
SPR along with the dump and instructions on reproducing the problem.
Data: NODE - CI node number of remote system
ERR - Error code returned by SC.CON
>,,<DB%NND>) ;[7.1210]
ECSKED ;Back to normal again
PIOFF ;Interrupts off again
CFSDM1: AOBJN Q1,TOP. ;Continue with next node
ENDDO. ;All done - we have notified the cluster
PION ;Allow interrupts again
BUG.(HLT,CFCLDP,CFSSRV,SOFT,<CFSSRV - Forced cluster dump>,,<
Cause: A call was made to CFSDMP to force a cluster dump. The other systems
in the cluster should have crashed with a KLPDMP BUGHLT. This occurs
when location 67 has a non-zero value or it the code actually calls
into CFSDMP directly.
Action: If the cluster dump was not performed legitimately, then it is possible
that the monitor mistakenly trashed location 67 causing the cluster
dump. In this case, an SPR should be submitted along with the dump(s)
from the systems and any insturctions on reproducing the problem.
>)
SUBTTL Miscellaneous Interfaces -- ILLGET (Illegal return from CFSGET)
;Here if CFSGET does anything unexpected
ILLGET: BUG.(HLT,CFSIGT,CFSSRV,SOFT,<CFSSRV - Illegal return from CFSGET>,,<
Cause: A call to CFSGET, CFSGTT or CFSGTL returns +1 even though a
wait-until-successful was requested.
>)
SUBTTL Miscellaneous Interfaces -- CFSKPD (KLIPA Failure)
;Routine to crash if someone tries to connect after we've been dead for
;sometime. This routine is called whenever we get connected another
;CFS SYSAP and we had previously been off of the CI for some time.
;We have to crash in that case because the two systems may be out
;of synch wrt the shared structures and may permanently interlock
;one another against referencing those structures.
CFSDIE: BUG.(HLT,CFSKPD,CFSSRV,HARD,<CFSSRV - The KLIPA failed>,,<
Cause: The KLIPA hardware or the CI has failed and CFS cannot continue.
Action: Have field service check out the system's CI20.
>)
CFNCNT: BUG.(HLT,CFZCNT,CFSSRV,SOFT,<CFSSRV - Zero HSHCNT before decrement>,,<
Cause: A routine wants to decrement the resource share count but the count is
already zero.
>)
SUBTTL Miscellaneous Interfaces -- ONLINE (CFS connection BUGINF)
;Call ONLINE when this node is getting a connection from another node.
ONLINE: SAVET
MOVE T3,CFSHNM(T1) ;Get serial number
LSH T3,-4 ;right-justify it
MOVE T1,CFSHST(T1) ;Get CID
CALL SC.NOD ;Get node number
IFN DEBUG,<
BUG.(INF,CFCONN,CFSSRV,SOFT,<CFSSRV - CFS connection>,<<T2,NODE>,<T1,CID>,<T3,SERNUM>>,<
Cause: A CFS connection has been received from another node on the CI20.
Data: NODE - Number of connecting node
CID - Connect ID
SERNUM - Serial number of remote node
>,,<DB%NND>) ;[7.1210]
> ;IFN DEBUG
CALLRET PYCON ;INFORM PHYSIO OF ONLINE
SUBTTL Miscellaneous Interfaces -- CFDISC (CFS disconnect BUGINF)
;Call OFLINE when a disconnect is read from a remote node on the CI.
IFN DEBUG,<
OFLINE: SAVET
MOVE T3,CFSHNM(T1) ;Get serial number
LSH T3,-4 ;right-justify it
MOVE T1,CFSHST(T1) ;Get CID
CALL SC.NOD ;Get node number
BUG.(INF,CFDISC,CFSSRV,SOFT,<CFSSRV - CFS disconnect>,<<T2,NODE>,<T1,CID>,<T3,SERNUM>>,<
Cause: A CFS disconnect request has been received from a remote node on the
CI20.
Data: NODE - Remote node number
CID - Connect ID
SERNUM - Serial number of remote node
>,,<DB%NND>) ;[7.1210]
RET
> ;IFN DEBUG
SUBTTL Miscellaneous Interfaces -- PHYNOL (Declare the disks offline)
;PHYNOL
;
; T3/ CONNECT ID OF NODE GOING OFFLINE
;
PHYNOL::SAVET ;Save everything just in case
MOVE T1,T3 ;Get the connect ID
CALL SC.NOD ;Get the node number
CALLRET PYCOFF ;And declare offline
SUBTTL End of CFSSRV
TNXEND
END