<> <> <> <<>> <> <<>> DIRECTORY Camelot, CamelotRecoverable, IO USING [int, PutFR], Mach, Process USING [Detach, MsecToTicks, Pause], Rope, YggBuffMan, YggDIDMap, YggdrasilInit, YggEnvironment; <<>> YggdrasilInitImpl: CEDAR PROGRAM IMPORTS Camelot, CamelotRecoverable, Mach, IO, Process, YggBuffMan, YggDIDMap, YggdrasilInit EXPORTS YggdrasilInit, YggEnvironment ~ BEGIN <> dsPort: PUBLIC Mach.portT; serverID: PUBLIC Camelot.serverIdT; tsPort: PUBLIC Mach.portT; mPort: PUBLIC Mach.portT; sPort: PUBLIC Mach.portT; dsqSharedMemAddr: PUBLIC Mach.vmAddressT; tPort: PUBLIC Mach.portT; aPort: PUBLIC Mach.portT; atPort: PUBLIC Mach.portT; taPort: PUBLIC Mach.portT; applicationID: PUBLIC Camelot.applicationIdT; <> camlibServerPort: Mach.portT; CamelotRecoveryComplete: BOOL _ FALSE; ReadyForRecovery: PUBLIC BOOL _ FALSE; <> <<>> InitSeqDescList: Camelot.ListOfSegmentDesc; InitSeqPortList: Mach.ListOfPorts; InitializePart1: PUBLIC PROC [] ~ { <> <> <> fullSeqDescList: Camelot.ListOfSegmentDesc; fullSeqPortList: Mach.ListOfPorts; firstTime: BOOL _ FALSE; kernCode: Mach.kernReturnT; { -- InitializeGlobalData calling to ServerInit dsPort _ GetTheDSPort[]; [serverID: serverID, tsPort: tsPort, mPort: mPort, sPort: sPort, sharedMemAddr: dsqSharedMemAddr, seqDescList: InitSeqDescList, seqPortList: InitSeqPortList, kernCode: kernCode] _ Camelot.DSInitialize[dsPort: dsPort, raiseSignal: TRUE]; Camelot.DSQInit[dsqSharedMemAddr]; }; TRUSTED {Process.Detach[FORK NotifyHandlerProcess[]];}; -- CamlibInitServerInternal [fullSeqDescList, fullSeqPortList] _ CamelotRecoverable.CamelotRecoverableInit[]; IF fullSeqDescList = NIL THEN fullSeqDescList _ InitSeqDescList ELSE { FOR fsdl: Camelot.ListOfSegmentDesc _ fullSeqDescList, fsdl.rest UNTIL fsdl = NIL DO IF fsdl.rest = NIL THEN {fsdl.rest _ InitSeqDescList; EXIT}; ENDLOOP; }; IF fullSeqPortList = NIL THEN fullSeqPortList _ InitSeqPortList ELSE { FOR lop: Mach.ListOfPorts _ fullSeqPortList, lop.rest UNTIL lop = NIL DO IF lop.rest = NIL THEN {lop.rest _ InitSeqPortList; EXIT}; ENDLOOP; }; firstTime _ RecoverSegments[fullSeqDescList, fullSeqPortList, TRUE]; -- CamlibInitServerInternal }; InitializePart2: PUBLIC PROC [serverName: Rope.ROPE, applName: Rope.ROPE] RETURNS [firstTime: BOOL _ FALSE] ~ { firstTime _ RecoverSegments[InitSeqDescList, InitSeqPortList, FALSE]; -- CamlibInitServerInternal [] _ Mach.portRestrict[Mach.taskSelf[], sPort, TRUE]; -- CamlibInitServerInternal TRUSTED {Process.Detach[FORK SystemMessageHandler[]];}; -- CamlibInitServerInternal { -- PublicizeService [newPort: camlibServerPort] _ Mach.portAllocate[Mach.taskSelf[], TRUE]; [] _ Mach.netnameCheckIn[Mach.nameServerPort[], serverName, Mach.taskSelf[], camlibServerPort, TRUE]; }; [] _ Mach.portUnrestrict[Mach.taskSelf[], camlibServerPort, TRUE]; TRUSTED {Process.Detach[FORK RequestHandler[]];}; <> ReadyForRecovery _ TRUE; WHILE ~CamelotRecoveryComplete DO Process.Pause[Process.MsecToTicks[50]] ENDLOOP; { -- TA_AddApplication setup tPortList: Mach.ListOfPorts; [portList: tPortList] _ Camelot.CALookup[Mach.nameServerPort[], "TranPort", "", 1, 1, TRUE]; IF tPortList = NIL THEN ERROR; IF tPortList.rest # NIL THEN ERROR; tPort _ tPortList.first; [newPort: atPort] _ Mach.portAllocate[Mach.taskSelf[], TRUE]; [] _ Mach.portRestrict[Mach.taskSelf[], atPort, TRUE]; [applicationID: applicationID, taPort: taPort] _ Camelot.TAAddApplication[tPort: tPort, atPort: atPort, authName: applName, raiseSignal: TRUE]; TRUSTED {Process.Detach[FORK ApplSysMsgHandler[]];}; }; YggDIDMap.InitDIDMap[firstTime]; -- call after recovery completes and TAAddApplication }; <<>> RecoveryComplete: PUBLIC PROC [] ~ { CamelotRecoveryComplete _ TRUE; }; <<>> <> <<>> RecoverSegments: PROC [seqDescList: Camelot.ListOfSegmentDesc, seqPortList: Mach.ListOfPorts, firstPass: BOOL] RETURNS [firstTime : BOOL ] ~ { <> <> < srServer->YggSRProcsImpl-> ??). Finally, a SR_RecoveryComplete message causes RecoveryComplete to be called.>> firstTime _ YggBuffMan.InitializeFilePageMgr[seqDescList: seqDescList, seqPortList: seqPortList, firstPass: firstPass]; }; <> <<>> NotifyHandlerProcess: PROC [] ~ { <> taskNotifyPort: Mach.portT; inMsg: REF Camelot.camlibSysReqMsgT; np: REF Mach.notificationT; taskNotifyPort _ Mach.taskNotify[]; inMsg _ NEW[Camelot.camlibSysReqMsgT]; DO inMsg.head.msgSize _ BYTES[Camelot.camlibMsgT]; inMsg.head.msgLocalPort _ taskNotifyPort; TRUSTED { recCode: Mach.msgReturnT _ -1; recCode _ Mach.msgReceive[header: LOOPHOLE[inMsg], option: Mach.MsgOptionNone, timeout: 0, raiseSignal: TRUE]; IF recCode = Mach.RcvTimedOut THEN EXIT; np _ LOOPHOLE[inMsg]; }; IF np.notifyHeader.msgId # Mach.NotifyPortDeleted THEN SIGNAL Mach.MachAnomaly[IO.PutFR["Got a message on the notify port that was not NOTIFY_PORT_DELETED; msg_id is %g",IO.int[np.notifyHeader.msgId]]] ELSE { SELECT np.notifyPort FROM Mach.nameServerPort[] => SIGNAL Mach.MachAnomaly[IO.PutFR["Got a message on the notify port that the name server connection failed!"]]; dsPort => SIGNAL Mach.MachAnomaly[IO.PutFR["Got a message on the notify port that the DiskMan (DS) connection failed!"]]; ENDCASE => SIGNAL Mach.MachAnomaly[IO.PutFR["Got a message on the notify port that some random connection failed! (port # %g)", IO.int[np.notifyPort]]]; }; ENDLOOP; }; SystemMessageHandler: PROC [] ~ { inMsg: REF Camelot.camlibSysReqMsgT; outMsg: REF Camelot.camlibSysRepMsgT; inMsg _ NEW[Camelot.camlibSysReqMsgT]; outMsg _ NEW[Camelot.camlibSysRepMsgT]; DO recCode: Mach.msgReturnT _ -1; sendCode: Mach.msgReturnT _ -1; inMsg.head.msgSize _ BYTES[Camelot.camlibMsgT]; inMsg.head.msgLocalPort _ sPort; outMsg.retcode _ Mach.MigNoReply; TRUSTED {recCode _ Mach.msgReceive[header: LOOPHOLE[inMsg], option: Mach.MsgOptionNone, timeout: 0, raiseSignal: TRUE];}; IF recCode = Mach.RcvTimedOut THEN EXIT; IF ~YggdrasilInit.STServer[inMsg, outMsg] THEN { IF ~YggdrasilInit.SRServer[inMsg, outMsg] THEN SIGNAL Mach.MachAnomaly[IO.PutFR["Got a message on the sPort port that is unrecognized; message ID is %g!", IO.int[inMsg.head.msgId]]]; }; IF outMsg.retcode # Mach.MigNoReply THEN TRUSTED { sendCode _ Mach.msgSend[LOOPHOLE[outMsg], Mach.MsgOptionNone, 0, TRUE]; }; ENDLOOP; }; <> <> <> <<".st_server">> <<};>> <> <<};>> <<>> <> <> <> <<".sr_server">> <<};>> <> <<};>> RequestHandler: PROC [] ~ { inMsg: REF Camelot.camlibSysReqMsgT; inMsg _ NEW[Camelot.camlibSysReqMsgT]; DO recCode: Mach.msgReturnT _ -1; inMsg.head.msgSize _ BYTES[Camelot.camlibMsgT]; inMsg.head.msgLocalPort _ Mach.PortEnabled; TRUSTED {recCode _ Mach.msgReceive[header: LOOPHOLE[inMsg], option: Mach.MsgOptionNone, timeout: 0, raiseSignal: TRUE];}; IF recCode = Mach.RcvTimedOut THEN EXIT; SIGNAL Mach.MachAnomaly[IO.PutFR["Got a message on some random port that is unrecognized; port number %gmessage ID is %g!", IO.int[inMsg.head.msgId], IO.int[inMsg.head.msgLocalPort]]]; ENDLOOP; }; ApplSysMsgHandler: PROC [] ~ { <> inMsg: REF Camelot.camlibSysReqMsgT; outMsg: REF Camelot.camlibSysRepMsgT; inMsg _ NEW[Camelot.camlibSysReqMsgT]; outMsg _ NEW[Camelot.camlibSysRepMsgT]; DO recCode: Mach.msgReturnT _ -1; sendCode: Mach.msgReturnT _ -1; inMsg.head.msgSize _ BYTES[Camelot.camlibMsgT]; inMsg.head.msgLocalPort _ atPort; outMsg.retcode _ Mach.MigNoReply; TRUSTED {recCode _ Mach.msgReceive[header: LOOPHOLE[inMsg], option: Mach.MsgOptionNone, timeout: 0, raiseSignal: TRUE];}; IF recCode = Mach.RcvTimedOut THEN EXIT; IF YggdrasilInit.ATServer[inMsg, outMsg] THEN { IF outMsg.retcode # Mach.MigNoReply THEN TRUSTED { sendCode _ Mach.msgSend[LOOPHOLE[outMsg], Mach.MsgOptionNone, 0, TRUE]; }; } ELSE SIGNAL Mach.MachAnomaly[IO.PutFR["Got a message on the atPort port that is unrecognized; message ID is %g!", IO.int[inMsg.head.msgId]]]; ENDLOOP; }; <> <> <> <<".at_server">> <<};>> <> <<};>> <<>> <<>> <> GetTheDSPort: PROC RETURNS[dsPort: Mach.portT] ~ { <> intPortSet: Mach.portArrayT; intPortArrayCount: INT; kernCode: Mach.kernReturnT; TRUSTED { [intPortSet: intPortSet, intPortArrayCount: intPortArrayCount, kernCode: kernCode] _ Mach.MachPortsLookup[targetTask: Mach.taskSelf[], raiseSignal: TRUE]; IF intPortArrayCount < Mach.MachPortsSlotsUsed THEN ERROR; dsPort _ (intPortSet+ UNITS[Mach.portArrayT] *Mach.MachPortsSlotsUsed)^; }; [] _ Mach.vmDeallocate[Mach.taskSelf[], LOOPHOLE[intPortSet], BYTES[Mach.portArrayT]*intPortArrayCount, TRUE]; }; <<>> <<>> <> <> <> <<"+extern port_t GetDSPort();.$GetDSPort">> <<};>> <> <<};>> <<>> <<>> <> END.