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