<> <> <> <> <> <> <> DIRECTORY AccessControl, AlpineControl USING [TypeOfRestart], AlpineDebug, AlpineEnvironment USING [Conversation, FileID, nullFileID, FileStore, PageCount, TransID, VolumeID, VolumeGroupID], AlpineFile, AlpineIdentity USING [myLocalConversation], AlpineImport USING [Handle, Register], AlpineOwner, AlpineTransaction USING[Create, Finish], AlpineTransMgr, AlpineTransMgrRpcControl USING [InterfaceRecord, NewInterfaceRecord], AlpineVolume, AlpineZones USING [], ConversationTable USING [Initialize, Fetch], CoordinatorControl USING [Initialize, CallAfterAnalysisPass, CallAfterUpdatePass], File, FileBackdoor, FileControl USING [Initialize, CallBeforeUpdatePass, CallAfterUpdatePass, RegisterVolumeGroup], FileMap USING [Handle, Initialize, Register], FilePageMgr USING [ Create, InitializeFilePageMgr, ReadPages, UsePages, ReleaseVMPageSet, VMPageSet], OpenFileMap USING [Initialize], InitProcs USING [], LockControl USING [Initialize, ForkWatchdogProcess], LogControl USING [Format, Recover, ForkCheckpointProcess], Rope, RPC USING [Conversation, ConversationID, EncryptionKey, GetConversationID, MakeKey], SafeStorage USING [GetSystemZone], TransactionMap USING [GetHandle, GetTransID, Handle], WorkerControl USING [Initialize, CallAfterAnalysisPass, CallAfterUpdatePass]; InitProcsImpl: MONITOR IMPORTS AccessControl, AlpineImport, AlpineIdentity, AlpineTransaction, AlpineTransMgr, AlpineTransMgrRpcControl, ConversationTable, CoordinatorControl, File, FileBackdoor, FileControl, FileMap, FilePageMgr, LockControl, LogControl, OpenFileMap, Rope, RPC, SafeStorage, TransactionMap, WorkerControl EXPORTS AlpineControl, AlpineIdentity, AlpineZones, InitProcs = BEGIN VolumeID: TYPE = AlpineEnvironment.VolumeID; FileID: TYPE = AlpineEnvironment.FileID; FileStore: TYPE = AlpineEnvironment.FileStore; PageCount: TYPE = AlpineEnvironment.PageCount; ROPE: TYPE = Rope.ROPE; <> myFileStore: PUBLIC FileStore; myLogVolumeID: PUBLIC VolumeID; myEncryptionKey: PUBLIC RPC.EncryptionKey; myAlpineImportHandle: PUBLIC AlpineImport.Handle; myLocalConversation: PUBLIC RPC.Conversation; myLocalConversationID: PUBLIC RPC.ConversationID; static: PUBLIC ZONE _ SafeStorage.GetSystemZone[]; <> isInitialized: BOOL _ FALSE; isStarted: BOOL _ FALSE; Initialize: PUBLIC ENTRY PROC [ filePageMgrNormalChunks, filePageMgrLogChunks, filePageMgrLeaderChunks: NAT, coordinatorMapHashArraySlots, transactionMapHashArraySlots: NAT, fileMapHashArraySlots, openFileMapHashArraySlots: NAT, lockHashArraySlots: NAT, fileMapFinalizationQueueLength: NAT, nAccessCacheEntries: NAT, alpineWheels: ROPE] = { <> IF isInitialized THEN RETURN; FilePageMgr.InitializeFilePageMgr[ nNormalChunksInCache: filePageMgrNormalChunks, nLogChunksInCache: filePageMgrLogChunks, nLeaderChunksInCache: filePageMgrLeaderChunks]; ConversationTable.Initialize[17]; LockControl.Initialize[lockZoneInitialSize: 2048, hashArraySize: 256]; WorkerControl.Initialize[transactionMapHashArraySlots]; CoordinatorControl.Initialize[coordinatorMapHashArraySlots]; FileMap.Initialize[fileMapHashArraySlots, fileMapFinalizationQueueLength]; OpenFileMap.Initialize[openFileMapHashArraySlots]; FileControl.Initialize[]; AccessControl.InitVolatileData[ nAccessCacheEntries: nAccessCacheEntries, alpineWheels: alpineWheels]; isInitialized _ TRUE; }; Start: PUBLIC ENTRY PROC [ fileStore: FileStore, additionalVolumes: LIST OF ROPE _ NIL, logVolumeName: ROPE _ NIL, typeOfRestart: AlpineControl.TypeOfRestart, nLogPages, nOwners: INT] = { logVolume: File.Volume; logVolumeID: VolumeID; additionalVolumeIDs: LIST OF VolumeID _ NIL; IF logVolumeName=NIL THEN logVolumeName _ fileStore; { ENABLE UNWIND => NULL; IF NOT isInitialized THEN ERROR; IF isStarted THEN RETURN; IF (logVolume _ File.FindVolumeFromName[logVolumeName]) = NIL THEN { IF fileStore.Equal["Local.alpine", FALSE] THEN logVolume _ File.SystemVolume[] ELSE ERROR; }; FOR volNames: LIST OF ROPE _ additionalVolumes, volNames.rest WHILE volNames # NIL DO { volID: VolumeID = [File.GetVolumeID[File.FindVolumeFromName[volNames.first]]]; additionalVolumeIDs _ CONS[ volID, additionalVolumeIDs ]; } ENDLOOP; }; logVolumeID _ [File.GetVolumeID[logVolume]]; SELECT typeOfRestart FROM warmStart => NULL; coldStart => EraseFileStore[logVolumeID, fileStore]; resizeLog => ResizeLog[logVolumeID, nLogPages, fileStore]; createServer => { IF logVolume # File.SystemVolume[] THEN FileBackdoor.EraseVolume[logVolume]; CreateFileStore[logVolumeID, nLogPages, fileStore]; }; ENDCASE => ERROR; Recover[logVolume: logVolumeID, additionalVolumes: additionalVolumeIDs, initOwnerFile: typeOfRestart = createServer, nOwners: nOwners]; isStarted _ TRUE; }; IsStarted: PUBLIC ENTRY PROC [] RETURNS [BOOL] = { RETURN [isStarted]; }; CreateFileStore: PROC [ logVolume: VolumeID, logPages: PageCount, fileStore: FileStore] = { <> <> <> logFile, restartFile, backupBTree: FileID; logFile _ CreateFile[logVolume, logPages]; restartFile _ CreateFile[logVolume, 1]; SetRootFiles[logVolume, logFile, restartFile, backupBTree]; LogControl.Format[logVolume, logFile, restartFile, fileStore]; }; ResizeLog: PROC [ logVolume: VolumeID, logPages: PageCount, fileStore: FileStore] = { <> <> <> logFile, restartFile, ownerFile, backupBTree: FileID; [logFile, restartFile, ownerFile, backupBTree] _ GetRootFiles[logVolume]; File.Delete[File.LabeledOpen[File.FindVolumeFromID[logVolume], logFile] ! File.Error => SELECT why FROM unknownFile => CONTINUE; ENDCASE => REJECT ]; logFile _ CreateFile[logVolume, logPages]; SetRootFiles[logVolume, logFile, restartFile, ownerFile, backupBTree]; LogControl.Format[logVolume, logFile, restartFile, fileStore]; }; EraseFileStore: PROC [logVolume: VolumeID, fileStore: FileStore] = { <> <> <> logFile, restartFile: FileID; [logFile, restartFile, ] _ GetRootFiles[logVolume]; LogControl.Format[logVolume, logFile, restartFile, fileStore]; }; Recover: PROC [ logVolume: VolumeID, additionalVolumes: LIST OF VolumeID, initOwnerFile: BOOL, nOwners: INT] = { <> logFile, restartFile, ownerFile, newOwnerFileID: FileID; ownerFileTrans: TransactionMap.Handle; <> [logFile, restartFile, ] _ GetRootFiles[logVolume]; FileControl.RegisterVolumeGroup[ volumeGroupID: GetVolumeGroupID[logVolume], volumes: CONS[first: logVolume, rest: additionalVolumes]]; <> LogControl.Recover[logVolume, logFile, restartFile]; <> ownerFileTrans _ CreateLocalTrans[]; IF initOwnerFile THEN { ownerFile _ AccessControl.CreateAndInitializeOwnerFile[ conversation: AlpineIdentity.myLocalConversation, transHandle: ownerFileTrans, volGroupID: GetVolumeGroupID[logVolume], ownerFileVolID: logVolume, totalQuota: 10000, volumeGroupSize: 15000, overCommitQuotaDuringInitializeIfNeeded: TRUE, maxNumberOfOwnersAllowed: nOwners, nOwnerCacheEntries: 10]; SetOwnerRootFile[logVolume, ownerFile]; } ELSE ownerFile _ GetOwnerRootFile[logVolume]; newOwnerFileID _ AccessControl.RegisterVolumeGroup[ conversation: AlpineIdentity.myLocalConversation, transHandle: ownerFileTrans, volGroupID: GetVolumeGroupID[logVolume], ownerFileUniversalFile: [logVolume, ownerFile], nOwnerCacheEntries: 10]; IF ownerFile # newOwnerFileID THEN SetOwnerRootFile[logVolume, newOwnerFileID]; CommitLocalTrans[ownerFileTrans]; LogControl.ForkCheckpointProcess[ myFileStore: myFileStore, wakeupPeriodInSeconds: 60]; LockControl.ForkWatchdogProcess[ wakeupPeriod: 1000, abortWaitingRequestInterval: 30, abortInactiveGrantedRequestInterval: 20]; }; CreateLocalTrans: PROC [] RETURNS [TransactionMap.Handle] = { transID: AlpineEnvironment.TransID = AlpineTransaction.Create[ conversation: AlpineIdentity.myLocalConversation, createLocalWorker: TRUE]; RETURN [TransactionMap.GetHandle[transID]]; }; CommitLocalTrans: PROC [t: TransactionMap.Handle] = { IF AlpineTransaction.Finish[ conversation: AlpineIdentity.myLocalConversation, transID: TransactionMap.GetTransID[t], requestedOutcome: commit, continue: FALSE].outcome # commit THEN ERROR; }; CreateFile: PROC [volume: VolumeID, nPages: PageCount] RETURNS [createdFileID: FileID] = { NoteFileID: SAFE PROC [fileID: FileID] = CHECKED { createdFileID _ fileID }; FilePageMgr.Create[volumeID: volume, initialSize: nPages, proc: NoteFileID]; }; AlpineRootFileRecord: TYPE = MACHINE DEPENDENT RECORD [ logFile: FileID, restartFile: FileID, ownerFile: FileID, backupBTree: FileID ]; <> SetRootFiles: PROC [logVolume: VolumeID, logFile, restartFile: FileID, ownerFile, backupBTree: FileID _ AlpineEnvironment.nullFileID] = { rootVolume: File.Volume = File.FindVolumeFromID[logVolume]; rootFP: FileID _ FileBackdoor.GetRoot[rootVolume, $alpine].fp; IF rootFP = AlpineEnvironment.nullFileID THEN { rootFP _ CreateFile[logVolume, 1]; FileBackdoor.SetRoot[volume: rootVolume, root: $alpine, file: File.LabeledOpen[volume: rootVolume, fp: rootFP]]; }; { rootFileHandle: FileMap.Handle = FileMap.Register[volumeID: logVolume, fileID: rootFP]; chunk: FilePageMgr.VMPageSet = FilePageMgr.UsePages[fileHandle: rootFileHandle, pageRun: [firstPage: 0, count: 1]]; rootFileRecord: LONG POINTER TO AlpineRootFileRecord = LOOPHOLE[chunk.pages]; rootFileRecord^ _ [ logFile: logFile, restartFile: restartFile, ownerFile: ownerFile, backupBTree: backupBTree]; FilePageMgr.ReleaseVMPageSet[ vMPageSet: chunk, releaseState: writeIndividualWait, keep: FALSE]; }; }; GetRootFiles: PROC [logVolume: VolumeID] RETURNS [logFile, restartFile, ownerFile, backupBTree: FileID] = { rootVolume: File.Volume = File.FindVolumeFromID[logVolume]; rootFP: FileID _ FileBackdoor.GetRoot[rootVolume, $alpine].fp; IF rootFP = AlpineEnvironment.nullFileID THEN ERROR; { rootFileHandle: FileMap.Handle = FileMap.Register[volumeID: logVolume, fileID: rootFP]; chunk: FilePageMgr.VMPageSet = FilePageMgr.ReadPages[fileHandle: rootFileHandle, pageRun: [firstPage: 0, count: 1]]; rootFileRecord: LONG POINTER TO AlpineRootFileRecord = LOOPHOLE[chunk.pages]; [logFile: logFile, restartFile: restartFile, ownerFile: ownerFile, backupBTree: backupBTree] _ rootFileRecord^; FilePageMgr.ReleaseVMPageSet[ vMPageSet: chunk, releaseState: clean, keep: FALSE]; } }; SetOwnerRootFile: PROC [logVolume: VolumeID, ownerFile: FileID] = { rootVolume: File.Volume = File.FindVolumeFromID[logVolume]; rootFP: FileID _ FileBackdoor.GetRoot[rootVolume, $alpine].fp; IF rootFP = AlpineEnvironment.nullFileID THEN ERROR; { rootFileHandle: FileMap.Handle = FileMap.Register[volumeID: logVolume, fileID: rootFP]; chunk: FilePageMgr.VMPageSet = FilePageMgr.ReadPages[fileHandle: rootFileHandle, pageRun: [firstPage: 0, count: 1]]; rootFileRecord: LONG POINTER TO AlpineRootFileRecord = LOOPHOLE[chunk.pages]; rootFileRecord.ownerFile _ ownerFile; FilePageMgr.ReleaseVMPageSet[ vMPageSet: chunk, releaseState: writeIndividualWait, keep: FALSE]; } }; GetOwnerRootFile: PROC [logVolume: VolumeID] RETURNS [ownerRootFile: FileID] = { rootVolume: File.Volume = File.FindVolumeFromID[logVolume]; rootFP: FileID _ FileBackdoor.GetRoot[rootVolume, $alpine].fp; IF rootFP = AlpineEnvironment.nullFileID THEN ERROR; { rootFileHandle: FileMap.Handle = FileMap.Register[volumeID: logVolume, fileID: rootFP]; chunk: FilePageMgr.VMPageSet = FilePageMgr.ReadPages[fileHandle: rootFileHandle, pageRun: [firstPage: 0, count: 1]]; rootFileRecord: LONG POINTER TO AlpineRootFileRecord = LOOPHOLE[chunk.pages]; [ownerFile: ownerRootFile] _ rootFileRecord^; FilePageMgr.ReleaseVMPageSet[ vMPageSet: chunk, releaseState: clean, keep: FALSE]; } }; GetVolumeGroupID: PROC [volumeID: VolumeID] RETURNS [volumeGroupID: AlpineEnvironment.VolumeGroupID] = { <> ID: TYPE = RECORD [a, b, c: CARDINAL, sequence: LONG CARDINAL]; id: ID _ LOOPHOLE[volumeID]; id.sequence _ id.sequence - 1; RETURN [LOOPHOLE[id]]; }; <> CalledBeforeAnalysisPass: PUBLIC PROC [ fileStore: FileStore, logVolume: VolumeID] = { myFileStore _ fileStore; myLogVolumeID _ logVolume; myEncryptionKey _ RPC.MakeKey["RPC"]; myAlpineImportHandle _ AlpineImport.Register[fileStore]; myAlpineImportHandle.first.local _ TRUE; { interface: AlpineTransMgrRpcControl.InterfaceRecord _ AlpineTransMgrRpcControl.NewInterfaceRecord[]; interface.clientStubRegisterWorker _ RegisterWorker; interface.clientStubWorkerPrepare _ WorkerPrepare; interface.clientStubWorkerFinish _ WorkerFinish; interface.Refused _ AlpineTransMgr.Refused; myAlpineImportHandle.first.transMgrInterface _ interface; }; myLocalConversation _ ConversationTable.Fetch[myAlpineImportHandle]; myLocalConversationID _ RPC.GetConversationID[myLocalConversation]; }; RegisterWorker: PROCEDURE [interface: AlpineTransMgrRpcControl.InterfaceRecord, conversation: AlpineEnvironment.Conversation, trans: AlpineEnvironment.TransID] RETURNS [AlpineTransMgr.RegisterWorkerResult] = { RETURN AlpineTransMgr.RegisterWorker[conversation, trans]}; WorkerPrepare: PROCEDURE [interface: AlpineTransMgrRpcControl.InterfaceRecord, conversation: AlpineEnvironment.Conversation, trans: AlpineEnvironment.TransID, newTrans: AlpineEnvironment.TransID] RETURNS [AlpineTransMgr.WorkerState] = { RETURN AlpineTransMgr.WorkerPrepare[conversation, trans, newTrans]}; WorkerFinish: PROCEDURE [interface: AlpineTransMgrRpcControl.InterfaceRecord, conversation: AlpineEnvironment.Conversation, trans: AlpineEnvironment.TransID, requiredOutcome: AlpineTransMgr.RequiredOutcome] = { AlpineTransMgr.WorkerFinish[conversation, trans, requiredOutcome]}; CalledAfterAnalysisPass: PUBLIC PROC [] = { WorkerControl.CallAfterAnalysisPass[]; CoordinatorControl.CallAfterAnalysisPass[]; }; CalledBeforeUpdatePass: PUBLIC PROC [] = { FileControl.CallBeforeUpdatePass[]; }; CalledAfterUpdatePass: PUBLIC PROC [] = { FileControl.CallAfterUpdatePass[]; WorkerControl.CallAfterUpdatePass[]; CoordinatorControl.CallAfterUpdatePass[]; }; END.--InitProcsImpl CHANGE LOG Changed by MBrown on April 1, 1983 1:25 pm <> Changed by MBrown on January 31, 1984 5:32:54 pm PST <> <<>> <> <> <> <<>>