-- 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.