AlpTransactionV2Impl.mesa
Carl Hauser, November 13, 1987 1:50:26 pm PST
DIRECTORY
AEToCrAE,
CrAEToAE,
CrRPC,
AlpTransaction,
AlpFile,
AlpineFile,
AlpineEnvironment,
AlpineP2202V2,
AlpineEnvironmentP2201V1,
AlpInstanceV2Internal,
AlpInstance,
RPC,
XNSAuth;
AlpTransactionV2Impl:
CEDAR
MONITOR
LOCKS inst^ USING inst: AlpInstanceV2Internal.Instance
IMPORTS AEToCrAE, CrAEToAE, AlpineP2202V2, AlpineFile, CrRPC, RPC
EXPORTS AlpTransaction, AlpInstanceV2Internal
=
BEGIN OPEN ATC: AEToCrAE, CTA: CrAEToAE, AlpT: AlpTransaction, AlpF: AlpFile, AlpI: AlpInstance, AE: AlpineEnvironment;
TransWorkProc: TYPE = AlpInstanceV2Internal.TransWorkProc;
Exported to AlpInstanceV2Internal
DoTransWork:
PUBLIC
ENTRY
PROC [inst: AlpInstanceV2Internal.Instance, transHandle: AlpTransaction.Handle, work: TransWorkProc] ~ {
ENABLE UNWIND => NULL;
accessReason: AlpineEnvironmentP2201V1.NeededAccess;
lockReason: AlpineEnvironmentP2201V1.LockFailure;
operationReason: AlpineEnvironmentP2201V1.OperationFailure;
unknownReason: AlpineEnvironmentP2201V1.UnknownType;
crReason: CrRPC.ErrorReason;
{
ENABLE {
AlpineP2202V2.AccessFailed => {accessReason ← missingAccess; GOTO accessFailed};
AlpineP2202V2.LockFailed => {lockReason ← why; GOTO lockFailed};
AlpineP2202V2.OperationFailed => {operationReason ← why; GOTO operationFailed};
AlpineP2202V2.PossiblyDamaged => {GOTO possiblyDamaged};
AlpineP2202V2.StaticallyInvalid => {GOTO staticallyInvalid};
AlpineP2202V2.Unknown => {unknownReason ← what; GOTO unknown};
AlpineP2202V2.AuthenticationError => { GOTO auth };
CrRPC.Error =>
SELECT errorReason FROM
unknown, unknownClass, argsError, resultsError, bulkDataError, notImplemented, unknownOperation, notServerHandle, notClientHandle, addressInappropriateForClass, other => REJECT;
ENDCASE => { crReason ← errorReason; GOTO rpcErr};
};
work[inst.courierHandle, inst.session, transHandle.transID]
EXITS
accessFailed => ERROR AlpineFile.AccessFailed[CTA.NeededAccess[accessReason]];
lockFailed => ERROR AlpineFile.LockFailed[CTA.LockFailure[lockReason]];
operationFailed => ERROR AlpineFile.OperationFailed[CTA.OperationFailure[operationReason]];
possiblyDamaged => TRUSTED {ERROR AlpineFile.PossiblyDamaged};
staticallyInvalid => ERROR AlpineFile.StaticallyInvalid;
unknown => ERROR AlpineFile.Unknown[CTA.UnknownType[unknownReason]];
auth => {SIGNAL RPC.CallFailed[runtimeProtocol]; ERROR};
rpcErr =>
SELECT crReason
FROM
courierVersionMismatch => {SIGNAL RPC.CallFailed[stubProtocol]; ERROR};
rejectedNoSuchProgram, rejectedNoSuchVersion, rejectedNoSuchProcedure, communicationFailure, remoteClose => {SIGNAL RPC.CallFailed[unbound]; ERROR};
rejectedInvalidArgument, rejectedUnspecified, remoteError, cantConnectToRemote, protocolError => {SIGNAL RPC.CallFailed[runtimeProtocol]; ERROR};
ENDCASE => ERROR;
};
};
InstWorkProc: TYPE = PROC [rpc: CrRPC.Handle, session: AlpineP2202V2.Session];
DoInstWork:
ENTRY PROC [inst: AlpInstanceV2Internal.Instance, work: InstWorkProc] ~ {
ENABLE UNWIND => NULL;
accessReason: AlpineEnvironmentP2201V1.NeededAccess;
lockReason: AlpineEnvironmentP2201V1.LockFailure;
operationReason: AlpineEnvironmentP2201V1.OperationFailure;
unknownReason: AlpineEnvironmentP2201V1.UnknownType;
crReason: CrRPC.ErrorReason;
{
ENABLE {
AlpineP2202V2.AccessFailed => {accessReason ← missingAccess; GOTO accessFailed};
AlpineP2202V2.LockFailed => {lockReason ← why; GOTO lockFailed};
AlpineP2202V2.OperationFailed => {operationReason ← why; GOTO operationFailed};
AlpineP2202V2.PossiblyDamaged => {GOTO possiblyDamaged};
AlpineP2202V2.StaticallyInvalid => {GOTO staticallyInvalid};
AlpineP2202V2.Unknown => {unknownReason ← what; GOTO unknown};
AlpineP2202V2.AuthenticationError => { GOTO auth };
CrRPC.Error =>
SELECT errorReason FROM
unknown, unknownClass, argsError, resultsError, bulkDataError, notImplemented, unknownOperation, notServerHandle, notClientHandle, addressInappropriateForClass, other => REJECT;
ENDCASE => { crReason ← errorReason; GOTO rpcErr};
};
work[inst.courierHandle, inst.session]
EXITS
accessFailed => ERROR AlpineFile.AccessFailed[CTA.NeededAccess[accessReason]];
lockFailed => ERROR AlpineFile.LockFailed[CTA.LockFailure[lockReason]];
operationFailed => ERROR AlpineFile.OperationFailed[CTA.OperationFailure[operationReason]];
possiblyDamaged => TRUSTED {ERROR AlpineFile.PossiblyDamaged};
staticallyInvalid => ERROR AlpineFile.StaticallyInvalid;
unknown => ERROR AlpineFile.Unknown[CTA.UnknownType[unknownReason]];
auth => {SIGNAL RPC.CallFailed[runtimeProtocol]; ERROR};
rpcErr =>
SELECT crReason
FROM
courierVersionMismatch => {SIGNAL RPC.CallFailed[stubProtocol]; ERROR};
rejectedNoSuchProgram, rejectedNoSuchVersion, rejectedNoSuchProcedure, communicationFailure, remoteClose => {SIGNAL RPC.CallFailed[unbound]; ERROR};
rejectedInvalidArgument, rejectedUnspecified, remoteError, cantConnectToRemote, protocolError => {SIGNAL RPC.CallFailed[runtimeProtocol]; ERROR};
ENDCASE => ERROR;
};
};
Create:
PUBLIC
PROCEDURE
[instHandle: AlpI.Handle, createLocalWorker: BOOLEAN]
RETURNS [handle: AlpT.Handle]
=
BEGIN
Work: InstWorkProc ~ {
transID: AlpineEnvironmentP2201V1.TransID;
verifier: XNSAuth.Verifier;
[transID, verifier] ← AlpineP2202V2.CreateTransaction[rpc, session, createLocalWorker];
handle ← NEW[AlpT.Object ← [inst: instHandle, transID: CTA.TransID[transID]]];
};
DoInstWork[NARROW[instHandle.otherInterfaces.first], Work];
END;
CreateWithTransID:
PUBLIC
PROCEDURE
[instHandle: AlpI.Handle, transID: AE.TransID, createLocalWorker: BOOLEAN]
RETURNS [handle: AlpT.Handle]
=
BEGIN
Work: InstWorkProc ~ {
verifier: XNSAuth.Verifier;
handle ← NEW[AlpT.Object ← [inst: instHandle, transID: transID]];
IF createLocalWorker THEN verifier ← AlpineP2202V2.CreateWorker[rpc, session, ATC.TransID[transID], ATC.FileStore[instHandle.fileStore]];
};
DoInstWork[NARROW[instHandle.otherInterfaces.first], Work];
END;
CreateWorker:
PUBLIC
PROCEDURE
[handle: AlpT.Handle, coordinator: AE.FileStore]
=
BEGIN
Work: TransWorkProc ~ {
verifier: XNSAuth.Verifier;
verifier ← AlpineP2202V2.CreateWorker[rpc, session, ATC.TransID[transID], ATC.FileStore[coordinator]];
};
DoTransWork[NARROW[handle.inst.otherInterfaces.first], handle, Work];
END;
Finish:
PUBLIC
PROCEDURE
[handle: AlpT.Handle, requestedOutcome: AlpT.RequestedOutcome, continue: BOOLEAN]
RETURNS[outcome: AE.Outcome]
=
BEGIN
Work: TransWorkProc ~ {
verifier: XNSAuth.Verifier;
crTransID: AlpineEnvironmentP2201V1.TransID;
crOutcome: AlpineEnvironmentP2201V1.Outcome;
[crOutcome, crTransID, verifier] ← AlpineP2202V2.FinishTransaction[rpc, session, ATC.TransID[transID], ATC.CommitOrAbort[requestedOutcome], continue];
outcome ← CTA.Outcome[crOutcome];
handle.transID ← CTA.TransID[crTransID];
};
DoTransWork[NARROW[handle.inst.otherInterfaces.first], handle, Work];
END;
AssertAlpineWheel:
PUBLIC
PROCEDURE
[handle: AlpT.Handle, enable: BOOLEAN]
=
BEGIN
Work: TransWorkProc ~ {
verifier: XNSAuth.Verifier;
verifier ← AlpineP2202V2.AssertAlpineWheel[rpc, session, ATC.TransID[transID], enable];
};
DoTransWork[NARROW[handle.inst.otherInterfaces.first], handle, Work];
END;
GetVolumeGroup:
PUBLIC
PROCEDURE
[handle: AlpT.Handle, volumeGroupID: AE.VolumeGroupID, lock: AE.LockOption]
RETURNS[volumes: LIST OF AE.VolumeID]
=
BEGIN
Work: TransWorkProc ~ {
verifier: XNSAuth.Verifier;
crVolumes: AlpineEnvironmentP2201V1.VolumeIDs;
[crVolumes, verifier] ← AlpineP2202V2.GetGroup[rpc, session, ATC.TransID[transID], ATC.VolumeGroupID[volumeGroupID], ATC.LockOption[lock]];
volumes ← CTA.VolumeIDs[crVolumes];
};
DoTransWork[NARROW[handle.inst.otherInterfaces.first], handle, Work];
END;
GetNextVolumeGroup:
PUBLIC
PROCEDURE
[handle: AlpT.Handle, previousGroup: AE.VolumeGroupID, lock: AE.LockOption]
RETURNS[volumeGroupID: AE.VolumeGroupID]
=
BEGIN
Work: TransWorkProc ~ {
verifier: XNSAuth.Verifier;
crVolumeGroupID: AlpineEnvironmentP2201V1.VolumeGroupID;
[crVolumeGroupID, verifier] ← AlpineP2202V2.GetNextGroup[rpc, session, ATC.TransID[transID], ATC.VolumeGroupID[previousGroup], ATC.LockOption[lock]];
volumeGroupID ← CTA.VolumeGroupID[crVolumeGroupID];
};
DoTransWork[NARROW[handle.inst.otherInterfaces.first], handle, Work];
END;
GetEnclosingVolumeGroup:
PUBLIC
PROCEDURE
[handle: AlpT.Handle, volumeID: AE.VolumeID, lock: AE.LockOption]
RETURNS[volumeGroupID: AE.VolumeGroupID]
=
BEGIN
Work: TransWorkProc ~ {
verifier: XNSAuth.Verifier;
crVolumeGroupID: AlpineEnvironmentP2201V1.VolumeGroupID;
[crVolumeGroupID, verifier] ← AlpineP2202V2.GetEnclosingGroup[rpc, session, ATC.TransID[transID], ATC.VolumeID[volumeID], ATC.LockOption[lock]];
volumeGroupID ← CTA.VolumeGroupID[crVolumeGroupID];
};
DoTransWork[NARROW[handle.inst.otherInterfaces.first], handle, Work];
END;
CreateOwner:
PUBLIC
PROCEDURE
[handle: AlpT.Handle, volumeGroupID: AE.VolumeGroupID, owner: AE.OwnerName, properties: LIST OF AE.OwnerPropertyValuePair, enforceTotalQuota: BOOLEAN]
RETURNS[spaceLeftOnVolumeGroup: AE.PageCount]
=
BEGIN
Work: TransWorkProc ~ {
verifier: XNSAuth.Verifier;
crSpaceLeftOnVolumeGroup: AlpineEnvironmentP2201V1.PageCount;
[crSpaceLeftOnVolumeGroup, verifier] ← AlpineP2202V2.CreateOwner[rpc, session, ATC.TransID[transID], ATC.VolumeGroupID[volumeGroupID], ATC.OwnerName[owner], ATC.OwnerProperties[properties], enforceTotalQuota];
spaceLeftOnVolumeGroup ← CTA.PageCount[crSpaceLeftOnVolumeGroup];
};
DoTransWork[NARROW[handle.inst.otherInterfaces.first], handle, Work];
END;
DestroyOwner:
PUBLIC
PROCEDURE
[handle: AlpT.Handle, volumeGroupID: AE.VolumeGroupID, owner: AE.OwnerName]
=
BEGIN
Work: TransWorkProc ~ {
verifier: XNSAuth.Verifier;
verifier ← AlpineP2202V2.DestroyOwner[rpc, session, ATC.TransID[transID], ATC.VolumeGroupID[volumeGroupID], ATC.OwnerName[owner]];
};
DoTransWork[NARROW[handle.inst.otherInterfaces.first], handle, Work];
END;
ReadNextOwner:
PUBLIC
PROCEDURE
[handle: AlpT.Handle, volumeGroupID: AE.VolumeGroupID, previousOwner: AE.OwnerName, desiredProperties: AE.OwnerPropertySet]
RETURNS[owner: AE.OwnerName, properties: LIST OF AE.OwnerPropertyValuePair]
=
BEGIN
Work: TransWorkProc ~ {
verifier: XNSAuth.Verifier;
crOwner: AlpineEnvironmentP2201V1.OwnerName;
crProperties: AlpineEnvironmentP2201V1.OwnerProperties;
[crOwner, crProperties, verifier] ← AlpineP2202V2.NextOwner[rpc, session, ATC.TransID[transID], ATC.VolumeGroupID[volumeGroupID], ATC.OwnerName[previousOwner], ATC.OwnerPropertySet[desiredProperties]];
owner ← CTA.OwnerName[crOwner];
properties ← CTA.OwnerProperties[crProperties];
};
DoTransWork[NARROW[handle.inst.otherInterfaces.first], handle, Work];
END;
ReadOwnerProperties:
PUBLIC
PROCEDURE
[handle: AlpT.Handle, volumeGroupID: AE.VolumeGroupID, owner: AE.OwnerName, desiredProperties: AE.OwnerPropertySet]
RETURNS[properties: LIST OF AE.OwnerPropertyValuePair]
=
BEGIN
Work: TransWorkProc ~ {
verifier: XNSAuth.Verifier;
crProperties: AlpineEnvironmentP2201V1.OwnerProperties;
[crProperties, verifier] ← AlpineP2202V2.ReadOwnerProperties[rpc, session, ATC.TransID[transID], ATC.VolumeGroupID[volumeGroupID], ATC.OwnerName[owner], ATC.OwnerPropertySet[desiredProperties]];
properties ← CTA.OwnerProperties[crProperties];
};
DoTransWork[NARROW[handle.inst.otherInterfaces.first], handle, Work];
END;
WriteOwnerProperties:
PUBLIC
PROCEDURE
[handle: AlpT.Handle, volumeGroupID: AE.VolumeGroupID, owner: AE.OwnerName, overCommitQuotasIfNeeded: BOOLEAN, properties: LIST OF AE.OwnerPropertyValuePair]
=
BEGIN
Work: TransWorkProc ~ {
verifier: XNSAuth.Verifier;
verifier ← AlpineP2202V2.WriteOwnerProperties[rpc, session, ATC.TransID[transID], ATC.VolumeGroupID[volumeGroupID], ATC.OwnerName[owner], ATC.OwnerProperties[properties], NOT overCommitQuotasIfNeeded];
};
DoTransWork[NARROW[handle.inst.otherInterfaces.first], handle, Work];
END;
ReadOwnerDBProperties:
PUBLIC
PROCEDURE
[handle: AlpT.Handle, volumeGroupID: AE.VolumeGroupID]
RETURNS[nOwners, nEntriesUsed, nEntries: NAT, totalQuota, totalSpaceInUse, volumeGroupSize: AE.PageCount]
=
BEGIN
Work: TransWorkProc ~ {
verifier: XNSAuth.Verifier;
crTotalQuota, crTotalSpaceInUse, crVolumeGroupSize: AlpineEnvironmentP2201V1.PageCount;
[nOwners, nEntriesUsed, nEntries, crTotalQuota, crTotalSpaceInUse, crVolumeGroupSize, verifier] ← AlpineP2202V2.ReadOwnerDBProperties[rpc, session, ATC.TransID[transID], ATC.VolumeGroupID[volumeGroupID]];
totalQuota ← CTA.PageCount[crTotalQuota];
totalSpaceInUse ← CTA.PageCount[crTotalSpaceInUse];
volumeGroupSize ← CTA.PageCount[crVolumeGroupSize];
};
DoTransWork[NARROW[handle.inst.otherInterfaces.first], handle, Work];
END;
ReorganizeOwnerDB:
PUBLIC
PROCEDURE
[handle: AlpT.Handle, volumeGroupID: AE.VolumeGroupID, nEntries: NAT]
=
BEGIN
Work: TransWorkProc ~ {
verifier: XNSAuth.Verifier;
verifier ← AlpineP2202V2.ReorganizeOwnerDB[rpc, session, ATC.TransID[transID], ATC.VolumeGroupID[volumeGroupID], nEntries];
};
DoTransWork[NARROW[handle.inst.otherInterfaces.first], handle, Work];
END;
UnlockOwnerDB:
PUBLIC
PROCEDURE
[handle: AlpT.Handle, volumeGroupID: AE.VolumeGroupID]
=
BEGIN
Work: TransWorkProc ~ {
verifier: XNSAuth.Verifier;
verifier ← AlpineP2202V2.UnlockOwnerDB[rpc, session, ATC.TransID[transID], ATC.VolumeGroupID[volumeGroupID]];
};
DoTransWork[NARROW[handle.inst.otherInterfaces.first], handle, Work];
END;
END.