-- Copyright (C) 1983, 1985 by Xerox Corporation. All rights reserved. -- BootServerParmTajo.mesa, HGM, 18-Mar-85 0:22:25 DIRECTORY Ascii USING [CR], CmFile USING [Handle, TableError], Event USING [aboutToSwap], EventTypes USING [aboutToBoot, aboutToBootPhysicalVolume], MFile USING [AddNotifyProc, Handle, RemoveNotifyProc], Process USING [Yield], Put USING [Text], String USING [AppendChar, AppendString], StringLookUp USING [InTable, noMatch], Supervisor USING [ AddDependency, AgentProcedure, CreateSubsystem, RemoveDependency, SubsystemHandle], Time USING [AppendCurrent], Token USING [FreeTokenString, Item], BootServer USING [ ActivateServer, AddBootFileToList, AppendBFN, BootFileNumber, BootFileType, CreateServer, DeactivateServer, DeleteServer, ForgetBootFileList, MachineType, StringToBFN], BootServerDefs USING [PupBootServerOff, PupBootServerOn], BootServerFriends USING [ ActivateFileSystem, BootFile, DeactivateFileSystem, EnumerateBootTable], Indirect USING [Close, GetParmFileName, NextValue, OpenSection]; BootServerParmTajo: MONITOR IMPORTS CmFile, Event, MFile, Process, Put, String, StringLookUp, Supervisor, Time, Token, BootServer, BootServerDefs, BootServerFriends, Indirect = BEGIN OPEN BootServerDefs; useCount: CARDINAL ← 0; parmFileName: LONG STRING ← Indirect.GetParmFileName[]; broom: Supervisor.SubsystemHandle = Supervisor.CreateSubsystem[Broom]; BootServersOn: ENTRY PROCEDURE = BEGIN IF (useCount ← useCount + 1) = 1 THEN BEGIN Supervisor.AddDependency[client: broom, implementor: Event.aboutToSwap]; MFile.AddNotifyProc[Inspect, [parmFileName, null, readOnly], NIL]; BootServerFriends.ActivateFileSystem[]; Starter[]; END; END; Starter: INTERNAL PROCEDURE = BEGIN BootServer.CreateServer[]; [] ← FindBootFiles[]; BootServer.ActivateServer[]; BootServerDefs.PupBootServerOn[]; PrintMissingFiles[]; END; BootServersOff: ENTRY PROCEDURE = BEGIN IF useCount # 0 AND (useCount ← useCount - 1) = 0 THEN BEGIN Stopper[]; BootServerFriends.DeactivateFileSystem[]; MFile.RemoveNotifyProc[Inspect, [parmFileName, null, readOnly], NIL]; Supervisor.RemoveDependency[client: broom, implementor: Event.aboutToSwap]; END; END; Stopper: INTERNAL PROCEDURE = BEGIN BootServerDefs.PupBootServerOff[]; BootServer.DeactivateServer[]; BootServer.ForgetBootFileList[]; BootServer.DeleteServer[]; END; FindBootFiles: PROCEDURE RETURNS [BOOLEAN] = BEGIN cmFile: CmFile.Handle; Option: TYPE = {alto, pupD0, d0, dorado, dLion, dLionTrident, dicentra, other}; FileType: TYPE = {microcode, germ, boot, pup, other}; NextValue: PROCEDURE [ h: CmFile.Handle, table: LONG DESCRIPTOR FOR ARRAY Option OF LONG STRING] RETURNS [Option] = LOOPHOLE[Indirect.NextValue]; TranslateFileType: PROCEDURE [ LONG STRING, LONG DESCRIPTOR FOR ARRAY FileType OF LONG STRING, BOOLEAN, BOOLEAN] RETURNS [FileType] = LOOPHOLE[StringLookUp.InTable]; transMachineType: ARRAY Option OF BootServer.MachineType ← [ alto: alto, pupD0: d0, d0: d0, dorado: dorado, dLion: dLion, dLionTrident: dLionTrident, dicentra: dicentra, other: other]; transFileType: ARRAY FileType OF BootServer.BootFileType ← [ microcode: microcode, germ: germ, boot: boot, pup: pup, other: other]; optionTable: ARRAY Option OF LONG STRING ← [ alto: "Alto"L, pupD0: "Pup D0"L, d0: "D0"L, dorado: "Dorado"L, dLion: "DLion"L, dLionTrident: "DLionTrident"L, dicentra: "Dicentra"L, other: "Other"L]; typeTable: ARRAY FileType OF LONG STRING ← [ microcode: "Microcode"L, germ: "Germ"L, boot: "Boot"L, pup: "Pup"L, other: "Other"L]; cmFile ← Indirect.OpenSection["BootServer"L]; IF cmFile = NIL THEN BEGIN Message["Can't find [BootServer] section in parameter file"L]; RETURN[FALSE]; END; DO option: Option; machineType: BootServer.MachineType; fileType: FileType; bootFileType: BootServer.BootFileType; pup: BOOLEAN; fileName, bootFileNumberString: LONG STRING; bootFileNumber: BootServer.BootFileNumber; text: STRING = [200]; option ← NextValue[ cmFile, DESCRIPTOR[optionTable] ! CmFile.TableError => BEGIN IF name[0] # '; THEN Message["Unrecognized machine type: ", name]; RETRY; END]; SELECT option FROM LOOPHOLE[StringLookUp.noMatch] => EXIT; alto => BEGIN pup ← TRUE; bootFileType ← pup; END; pupD0, d0, dorado, dLion, dLionTrident, dicentra, other => BEGIN fileTypeString: LONG STRING ← Token.Item[cmFile, TRUE]; pup ← option = pupD0; fileType ← TranslateFileType[ fileTypeString, DESCRIPTOR[typeTable], TRUE, TRUE]; IF fileType ~IN FileType THEN BEGIN Message["Unrecognized boot file type: ", fileTypeString]; [] ← Token.FreeTokenString[fileTypeString]; LOOP; END; [] ← Token.FreeTokenString[fileTypeString]; bootFileType ← transFileType[fileType]; END; ENDCASE => ERROR; machineType ← transMachineType[option]; bootFileNumberString ← Token.Item[cmFile, TRUE]; bootFileNumber ← BootServer.StringToBFN[bootFileNumberString]; fileName ← Token.Item[cmFile, TRUE]; String.AppendString[text, fileName]; String.AppendString[text, " (#"L]; BootServer.AppendBFN[text, bootFileNumber]; String.AppendString[text, ") is "L]; SELECT machineType FROM alto => String.AppendString[text, "an Alto "L]; d0 => String.AppendString[text, "a D0"L]; dorado => String.AppendString[text, "a Dorado"L]; dLion => String.AppendString[text, "a DLion"L]; dLionTrident => String.AppendString[text, "a DLionTrident"L]; dicentra => String.AppendString[text, "a Dicentra"L]; ENDCASE => String.AppendString[text, "a ??"L]; SELECT bootFileType FROM microcode => String.AppendString[text, " Microcode"L]; germ => String.AppendString[text, " Germ"L]; boot => String.AppendString[text, " Boot file"L]; pup => String.AppendString[text, " Pup boot file"L]; ENDCASE => String.AppendString[text, " ?"L]; LogString[text]; BootServer.AddBootFileToList[ fileName, bootFileNumber, bootFileType, machineType, pup]; [] ← Token.FreeTokenString[fileName]; [] ← Token.FreeTokenString[bootFileNumberString]; ENDLOOP; Indirect.Close[cmFile]; RETURN[TRUE]; END; PrintMissingFiles: PROCEDURE = BEGIN PrintOne: PROCEDURE [bf: BootServerFriends.BootFile] = BEGIN IF bf.unknown THEN BEGIN text: STRING = [100]; Time.AppendCurrent[text]; String.AppendString[text, " BootServer: "L]; String.AppendString[text, bf.fileName]; String.AppendString[text, " (#"L]; BootServer.AppendBFN[text, bf.code]; String.AppendString[text, ") is not on this disk"L]; LogString[text]; DoSomeYields[]; END; END; BootServerFriends.EnumerateBootTable[PrintOne]; END; Message: PROCEDURE [s1, s2, s3, s4: LONG STRING ← NIL] = BEGIN text: STRING = [200]; String.AppendString[text, "BootServer: "L]; String.AppendString[text, s1]; IF s2 # NIL THEN String.AppendString[text, s2]; IF s3 # NIL THEN String.AppendString[text, s3]; IF s4 # NIL THEN String.AppendString[text, s4]; LogString[text]; END; LogString: PROCEDURE [text: LONG STRING] = BEGIN String.AppendChar[text, '.]; String.AppendChar[text, Ascii.CR]; Put.Text[NIL, text]; END; DoSomeYields: PROCEDURE = BEGIN THROUGH [0..100) DO Process.Yield[]; ENDLOOP; END; Inspect: ENTRY PROCEDURE [ name: LONG STRING, file: MFile.Handle, clientInstanceData: LONG POINTER] RETURNS [BOOLEAN] = BEGIN IF parmFileName = NIL THEN RETURN[FALSE]; Message["Recycling because a new version of "L, parmFileName, " arrived"L]; Stopper[]; Starter[]; RETURN[FALSE] END; Broom: ENTRY Supervisor.AgentProcedure = BEGIN SELECT event FROM EventTypes.aboutToBoot, EventTypes.aboutToBootPhysicalVolume => Stopper[]; ENDCASE => NULL; END; -- initialization BootServersOn[]; -- Autostartup via START trap END.