-- File: CedarSnapshotRollback.mesa
-- last edited by Levin: November 12, 1982 9:48 am
DIRECTORY
CedarSnapshot USING [],
CedarSnapshotPrivate USING [FilePoint, GetSnapshotPoint, nullFilePoint],
File USING [Delete, delete, ID, read, Unknown],
Snapshot USING [InLoad],
Volume USING [Close, GetStatus, ID, NeedsScavenging, nullID, systemID],
VolumeExtras USING [OpenVolume];
CedarSnapshotRollback: MONITOR LOCKS snapshotLock
IMPORTS CedarSnapshotPrivate, File, Snapshot, Volume, VolumeExtras
EXPORTS CedarSnapshot, CedarSnapshotPrivate
SHARES File =
BEGIN OPEN CedarSnapshotPrivate;
snapshotLock: PUBLIC MONITORLOCK;
-- Rollback --
RollBack: PUBLIC ENTRY PROCEDURE [volume: Volume.ID ← Volume.nullID] =
BEGIN
filePoint: FilePoint;
valid: BOOL;
IF volume = Volume.nullID THEN volume ← Volume.systemID;
[filePoint, valid] ← GetSnapshotPoint[volume, keep];
IF ~valid THEN RETURN;
BEGIN
ENABLE ANY => CONTINUE; -- shouldn't really happen --
volumeOpened: BOOLEAN ← FALSE;
IF Volume.GetStatus[volume] ~= open THEN
BEGIN
VolumeExtras.OpenVolume[volume: volume, readOnly: TRUE];
volumeOpened ← TRUE;
END;
Snapshot.InLoad[
pMicrocode: NIL, pGerm: NIL, countGerm: 0,
file: [fID: filePoint.fID, permissions: File.read], firstPage: filePoint.firstPage];
-- Note: execution normally continues inside Checkpoint. If the
-- above InLoad failed, we try to delete the offending checkpoint
-- file. However, if the volume is so badly messed up that it
-- requires scavenging, we leave it alone (note ENABLE ANY, above).
IF volumeOpened THEN
BEGIN
Volume.Close[volume: volume];
-- Using VolumeExtras.OpenVolume instead of Volume.Open keeps
-- the temporary files from being deleted.
VolumeExtras.OpenVolume[volume: volume, readOnly: FALSE];
END;
File.Delete[[filePoint.fID, File.delete] ! File.Unknown => CONTINUE];
[] ← GetSnapshotPoint[volume, clear];
IF volumeOpened THEN Volume.Close[volume: volume];
END;
END;
-- Delete --
Delete: PUBLIC ENTRY PROCEDURE [volume: Volume.ID ← Volume.nullID] =
BEGIN
filePoint: FilePoint;
volumeOpened: BOOLEAN ← FALSE;
IF volume = Volume.nullID THEN volume ← Volume.systemID;
IF Volume.GetStatus[volume] ~= open THEN
BEGIN
-- Using VolumeExtras.OpenVolume instead of Volume.Open keeps
-- the temporary files from being deleted.
VolumeExtras.OpenVolume[volume: volume, readOnly: FALSE
! Volume.NeedsScavenging => GO TO cantDelete];
volumeOpened ← TRUE;
END;
IF (filePoint ← GetSnapshotPoint[volume, keep].filePoint) ~= nullFilePoint THEN
File.Delete[[fID: filePoint.fID, permissions: File.delete] ! File.Unknown => CONTINUE];
[] ← GetSnapshotPoint[volume, clear];
IF volumeOpened THEN Volume.Close[volume: volume];
EXITS
cantDelete => NULL;
END;
-- Validate --
ValidateSnapshot: PUBLIC ENTRY PROC [volume: Volume.ID] RETURNS [BOOL] =
{RETURN[GetSnapshotPoint[volume, keep].valid]};
END.