Alpine: PROGRAM 2202 VERSION 1 = BEGIN DEPENDS UPON CHName (2) VERSION 0, AlpineEnvironment (2201) VERSION 1, Authentication(14) VERSION 2; AccessList: TYPE = AlpineEnvironment.AccessList; AccessRights: TYPE = AlpineEnvironment.AccessRights; ByteCount: TYPE = AlpineEnvironment.ByteCount; Credentials: TYPE = Authentication.Credentials; FileID: TYPE = AlpineEnvironment.FileID; FileStore: TYPE = AlpineEnvironment.FileStore; FileVersion: TYPE = AlpineEnvironment.FileVersion; LockFailure: TYPE = AlpineEnvironment.LockFailure; LockOption: TYPE = AlpineEnvironment.LockOption; NeededAccess: TYPE = AlpineEnvironment.NeededAccess; OpenFileID: TYPE = AlpineEnvironment.OpenFileID; OperationFailure: TYPE = AlpineEnvironment.OperationFailure; OwnerName: TYPE = AlpineEnvironment.OwnerName; OwnerPropertySet: TYPE = AlpineEnvironment.OwnerPropertySet; OwnerPropertyValuePair: TYPE = AlpineEnvironment.OwnerPropertyValuePair; PageCount: TYPE = AlpineEnvironment.PageCount; PageNumber: TYPE = AlpineEnvironment.PageNumber; PageRun: TYPE = AlpineEnvironment.PageRun; Property: TYPE = AlpineEnvironment.Property; PropertyValuePair: TYPE = AlpineEnvironment.PropertyValuePair; RecoveryOption: TYPE = AlpineEnvironment.RecoveryOption; ReferencePattern: TYPE = AlpineEnvironment.ReferencePattern; TransID: TYPE = AlpineEnvironment.TransID; UniversalFile: TYPE = AlpineEnvironment.UniversalFile; UnknownReason: TYPE = AlpineEnvironment.UnknownType; Verifier: TYPE = Authentication.Verifier; VolumeGroupID: TYPE = AlpineEnvironment.VolumeGroupID; VolOrVolGroupID: TYPE = AlpineEnvironment.VolOrVolGroupID; VolumeID: TYPE = AlpineEnvironment.VolumeID; FalseBool: TYPE = BOOLEAN; RESULTPageBuffer: TYPE = PageBuffer; VALUEPageBuffer: TYPE = PageBuffer; SessionToken: TYPE = ARRAY 2 OF UNSPECIFIED; Session: TYPE = RECORD [token: SessionToken, verifier: Verifier]; PropertySet: TYPE = AlpineEnvironment.PropertySet; PageBuffer: TYPE = SEQUENCE OF UNSPECIFIED; Properties: TYPE = AlpineEnvironment.Properties; allProperties: PropertySet = [TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE]; maxPagesPerRun: CARDINAL = 255; -- LAST[CARDINAL]/AlpineEnvironment.wordsPerPage AccessFailed: ERROR [missingAccess: NeededAccess] = 0; LockFailed: ERROR [why: LockFailure] = 1; OperationFailed: ERROR [why: OperationFailure] = 2; PossiblyDamaged: ERROR = 3; StaticallyInvalid: ERROR = 4; Unknown: ERROR [what: UnknownReason] = 5; AuthenticationError: ERROR [problem: Authentication.Problem] = 6; ConnectionError: ERROR [problem: ConnectionProblem] = 7; ConnectionProblem: TYPE = { noRoute(0), noResponse(1), transmissionHardware(2), transportTimeout(3), tooManyLocalConnections(4), tooManyRemoteConnections(5), missingCourier(6), missingProgram(7), missingProcedure(8), protocolMismatch(9), parameterInconsistency(10), invalidMessage(11), returnTimedOut(12), otherCallProblem(177777B) }; GVCredentials: TYPE = RECORD[ name: AlpineEnvironment.RName, pwd: STRING]; Logon: PROCEDURE [ service: CHName.Name, credentials: Credentials, gvCredentials: GVCredentials, verifier: Verifier ] RETURNS [ session: Session, replyVerifier: Verifier ] REPORTS [ AuthenticationError, ConnectionError ] = 0; Logoff: PROCEDURE [ session: Session ] REPORTS [ AuthenticationError, ConnectionError ] = 1; CreateTransaction: PROCEDURE [session: Session, createLocalWorker: BOOLEAN] RETURNS [transID: TransID, replyVerifier: Verifier] REPORTS [ AuthenticationError, AccessFailed, OperationFailed ] = 2; CreateWorker: PROCEDURE [session: Session, transID: TransID, coordinator: FileStore] RETURNS [replyVerifier: Verifier] REPORTS [ AuthenticationError, AccessFailed, Unknown ] = 3; AssertAlpineWheel: PROCEDURE [session: Session, transID: TransID, enable: BOOLEAN] RETURNS [replyVerifier: Verifier] REPORTS [ AuthenticationError, AccessFailed, OperationFailed, Unknown ] = 4; RequestedOutcome: TYPE = AlpineEnvironment.CommitOrAbort; Outcome: TYPE = AlpineEnvironment.Outcome; FinishTransaction: PROCEDURE [session: Session, transID: TransID, requestedOutcome: RequestedOutcome --{abort, commit}--, continue: BOOLEAN] RETURNS [outcome: Outcome --{abort, commit, unknown}--, newTrans: TransID, replyVerifier: Verifier] REPORTS [ AuthenticationError ] = 5; Open: PROCEDURE [session: Session, transID: TransID, universalFile: UniversalFile, access: AccessRights, lock: LockOption, recoveryOption: RecoveryOption, referencePattern: ReferencePattern] RETURNS [openFileID: OpenFileID, fileID: FileID, replyVerifier: Verifier] REPORTS [AccessFailed, AuthenticationError, LockFailed, OperationFailed, PossiblyDamaged, StaticallyInvalid, Unknown] = 6; Create: PROCEDURE [session: Session, transID: TransID, volumeID: VolOrVolGroupID, owner: OwnerName, initialSize: PageCount, recoveryOption: RecoveryOption, referencePattern: ReferencePattern] RETURNS [openFileID: OpenFileID, universalFile: UniversalFile, replyVerifier: Verifier] REPORTS [AccessFailed, AuthenticationError, OperationFailed, StaticallyInvalid, Unknown] = 7; Close: PROCEDURE [session: Session, openFileID: OpenFileID] RETURNS [replyVerifier: Verifier] REPORTS [AuthenticationError, Unknown] = 8; Delete: PROCEDURE [session: Session, openFileID: OpenFileID] RETURNS [replyVerifier: Verifier] REPORTS [AccessFailed, AuthenticationError, LockFailed, Unknown] = 9; GetUniversalFile: PROCEDURE [session: Session, openFileID: OpenFileID] RETURNS [universalFile: UniversalFile, replyVerifier: Verifier] REPORTS [AuthenticationError, Unknown] = 10; GetTransID: PROCEDURE [session: Session, openFileID: OpenFileID] RETURNS [transID: TransID, replyVerifier: Verifier] REPORTS [AuthenticationError, Unknown] = 11; GetAccessRights: PROCEDURE [session: Session, openFileID: OpenFileID] RETURNS [access: AccessRights, replyVerifier: Verifier] REPORTS [AuthenticationError, Unknown] = 12; GetLockOption: PROCEDURE [session: Session, openFileID: OpenFileID] RETURNS [lock: LockOption, replyVerifier: Verifier] REPORTS [AuthenticationError, Unknown] = 13; SetLockOption: PROCEDURE [session: Session, openFileID: OpenFileID, lock: LockOption] RETURNS [replyVerifier: Verifier] REPORTS [AuthenticationError, LockFailed, StaticallyInvalid, Unknown] = 14; GetRecoveryOption: PROCEDURE [session: Session, openFileID: OpenFileID] RETURNS [recoveryOption: RecoveryOption, replyVerifier: Verifier] REPORTS [AuthenticationError, Unknown] = 15; GetReferencePattern: PROCEDURE [session: Session, openFileID: OpenFileID] RETURNS [referencePattern: ReferencePattern, replyVerifier: Verifier] REPORTS [AuthenticationError, Unknown] = 16; SetReferencePattern: PROCEDURE [session: Session, openFileID: OpenFileID, referencePattern: ReferencePattern] RETURNS [replyVerifier: Verifier] REPORTS [AuthenticationError, StaticallyInvalid, Unknown] = 17; ReadPages: PROCEDURE [session: Session, openFileID: OpenFileID, pageRun: PageRun, lock: LockOption] RETURNS [pageBuffer: RESULTPageBuffer, replyVerifier: Verifier] REPORTS [AuthenticationError, OperationFailed, LockFailed, StaticallyInvalid, Unknown] = 18; WritePages: PROCEDURE [session: Session, openFileID: OpenFileID, pageRun: PageRun, pageBuffer: VALUEPageBuffer, lock: LockOption] RETURNS [replyVerifier: Verifier] REPORTS [AuthenticationError, AccessFailed, LockFailed, OperationFailed, StaticallyInvalid, Unknown] = 19; LockPages: PROCEDURE [session: Session, openFileID: OpenFileID, pageRun: PageRun, lock: LockOption ] RETURNS [replyVerifier: Verifier] REPORTS [AuthenticationError, LockFailed, StaticallyInvalid, Unknown] = 20; UnlockPages: PROCEDURE [session: Session, openFileID: OpenFileID, pageRun: PageRun] RETURNS [replyVerifier: Verifier] REPORTS [AuthenticationError, StaticallyInvalid, Unknown] = 21; ReadProperties: PROCEDURE [session: Session, openFileID: OpenFileID, desiredProperties: PropertySet, lock: LockOption] RETURNS [properties: Properties, replyVerifier: Verifier] REPORTS [AuthenticationError, LockFailed, StaticallyInvalid, Unknown] = 22; WriteProperties: PROCEDURE [session: Session, openFileID: OpenFileID, properties: Properties, lock: LockOption] RETURNS [replyVerifier: Verifier] REPORTS [AccessFailed, AuthenticationError, LockFailed, OperationFailed, StaticallyInvalid, Unknown] = 23; UnlockVersion: PROCEDURE [session: Session, openFileID: OpenFileID] RETURNS [replyVerifier: Verifier] REPORTS [Unknown] = 24; IncrementVersion: PROCEDURE [session: Session, openFileID: OpenFileID, increment: LONG INTEGER] RETURNS [replyVerifier: Verifier] REPORTS [AccessFailed, AuthenticationError, StaticallyInvalid, Unknown] = 25; GetSize: PROCEDURE [session: Session, openFileID: OpenFileID, lock: LockOption] RETURNS [size: PageCount, replyVerifier: Verifier] REPORTS [AuthenticationError, LockFailed, Unknown] = 26; SetSize: PROCEDURE [session: Session, openFileID: OpenFileID, size: PageCount, lock: LockOption] RETURNS [replyVerifier: Verifier] REPORTS [AuthenticationError, AccessFailed, LockFailed, OperationFailed, StaticallyInvalid, Unknown] = 27; UnlockFile: PROCEDURE [session: Session, openFileID: OpenFileID] RETURNS [replyVerifier: Verifier] REPORTS [AuthenticationError, StaticallyInvalid, Unknown] = 28; OwnerProperties: TYPE = AlpineEnvironment.OwnerProperties; ReadOwnerProperties: PROCEDURE [session: Session, transID: TransID, volumeGroupID: VolumeGroupID, owner: OwnerName, desiredProperties: OwnerPropertySet ] RETURNS [properties: OwnerProperties, replyVerifier: Verifier] REPORTS [AuthenticationError, LockFailed, StaticallyInvalid, Unknown] = 29; WriteOwnerProperties: PROCEDURE [session: Session, transID: TransID, volumeGroupID: VolumeGroupID, owner: OwnerName, properties: OwnerProperties, enforceTotalQuota: BOOLEAN] RETURNS [replyVerifier: Verifier] REPORTS [AuthenticationError, AccessFailed, LockFailed, OperationFailed, StaticallyInvalid, Unknown] = 30; CreateOwner: PROCEDURE [session: Session, transID: TransID, volumeGroupID: VolumeGroupID, owner: OwnerName, properties: OwnerProperties, enforceTotalQuota: BOOLEAN] RETURNS [spaceLeftOnVolumeGroup: PageCount, replyVerifier: Verifier] REPORTS [AuthenticationError, AccessFailed, LockFailed, OperationFailed, StaticallyInvalid, Unknown] = 31; DestroyOwner: PROCEDURE [session: Session, transID: TransID, volumeGroupID: VolumeGroupID, owner: OwnerName] RETURNS [replyVerifier: Verifier] REPORTS [AuthenticationError, AccessFailed, LockFailed, OperationFailed, StaticallyInvalid, Unknown] = 31; NextOwner: PROCEDURE [session: Session, transID: TransID, volumeGroupID: VolumeGroupID, previousOwner: OwnerName, desiredProperties: OwnerPropertySet] RETURNS [owner: OwnerName, properties: OwnerProperties, replyVerifier: Verifier] REPORTS [AuthenticationError, AccessFailed, LockFailed, StaticallyInvalid, Unknown] = 32; ReadOwnerDBProperties: PROCEDURE [session: Session, transID: TransID, volumeGroupID: VolumeGroupID] RETURNS [nOwners, nEntriesUsed, nEntries: LONG INTEGER, totalQuota, totalSpaceInUse, volumeGroupSize: PageCount, replyVerifier: Verifier] REPORTS [AuthenticationError, AccessFailed, LockFailed, Unknown] = 33; ReorganizeOwnerDB: PROCEDURE [session: Session, transID: TransID, volumeGroupID: VolumeGroupID, nEntries: LONG INTEGER] RETURNS [replyVerifier: Verifier] REPORTS [AuthenticationError, AccessFailed, LockFailed, OperationFailed, Unknown] = 34; UnlockOwnerDB: PROCEDURE [session: Session, transID: TransID, volumeGroupID: VolumeGroupID] RETURNS [replyVerifier: Verifier] REPORTS [AuthenticationError, StaticallyInvalid, Unknown] = 35; GetNextGroup: PROCEDURE [session: Session, transID: TransID, previousGroup: VolumeGroupID, lock: LockOption] RETURNS [volumeGroupID: VolumeGroupID, replyVerifier: Verifier] REPORTS[AuthenticationError, Unknown] = 36; VolumeIDs: TYPE = AlpineEnvironment.VolumeIDs; GetGroup: PROCEDURE [session: Session, transID: TransID, volumeGroupID: VolumeGroupID, lock: LockOption] RETURNS [volumes: VolumeIDs, replyVerifier: Verifier] REPORTS[AuthenticationError, Unknown] = 37; GetEnclosingGroup: PROCEDURE [session: Session, transID: TransID, volumeID: VolumeID, lock: LockOption] RETURNS [volumeGroupID: VolumeGroupID, replyVerifier: Verifier] REPORTS[AuthenticationError, Unknown] = 38; END. IAlpine1.cr Copyright c 1986 by Xerox Corporation. All rights reserved. Bill Jackson (bj) August 9, 1986 8:35:34 pm PDT Carl Hauser, November 9, 1987 2:52:23 pm PST Copied types Credentials: TYPE = RECORD [ primary: PrimaryCredentials, secondary: SecondaryCredentials ]; Above renaming because of Scirocco bug which tries to make up at type for "Unknown" and call it "UnknownType". Primitive types Array types Sequence Types Constants This is all that can be described with a DESCRIPTOR (PageBuffer). The restriction applies only to ReadPages and WritePages. Remote Errors Raised by any operation if passed unreasonable arguments, where unreasonableness may be determined statically and does not depend on the state of the file system. The most common cause is an enumerated or subrange argument out of bounds, which can generally occur only if the client passed it through a LOOPHOLE. AuthenticationError: ERROR [problem: AuthenticationProblem, type: SecondaryType] = 7; AuthenticationProblem: TYPE = { primaryCredentialInvalid(0), verifierInvalid(1), verifierExpired(2), verifierRefused(3), primaryCredentialsExpired(4), inappropriatePrimaryCredentials(5), secondaryCredentialsRequired(6), secondaryCredentialsTypeInvalid(7), secondaryCredentialsValueInvalid(8) }; communication problems resource problems remote program implementation problems miscellaneous Remote procedures Session Control Transaction Control ! OperationFailed {busy}; Call from client to coordinator. Creates a new transaction, for which the called Alpine instance is to be the coordinator. If createLocalWorker, this in turn calls CreateWorker[conversation, transID, ], and is guaranteed not to raise any of the errors raised by CreateWorker. ! Unknown {coordinator, transID}; Call from client to worker. Informs the called Alpine instance that it is to server as a worker under an existing transaction transID which is being coordinated by the Alpine instance identified by coordinator. This procedure returns (i.e. does not raise an error) iff trans becomes active (prepared to do work) on the called Alpine instance. Of course, there is no guarantee that this state will last for any length of time. ! OperationFailed {regServersUnavailable, notAlpineWheel}, Unknown {transID}. When called with enable = TRUE, causes all subsequent calls for this (conversation, transID) pair to pass all access control checks without further checking; raises OperationFailed [notAlpineWheel] if the caller identified by conversation is not a member of the AlpineWheels group for this server. When called with enable = FALSE, causes normal access control checking to resume for this (conversation, transID) pair. ! (none); Call from client to coordinator. Requests that the transaction be finished in the specified way. If the transaction has already committed or aborted, Finish simply returns the outcome. Otherwise, Finish waits if necessary to assure a known outcome (which may differ from the one requested) and returns that outcome. newTrans is meaningful only if requestedOutcome = commit, continue = TRUE, and outcome = commit. Procedures that create OpenFileIDs Opens an existing file described by volume and file for access under trans, and returns an OpenFileID that designates the open file. The returned FileID may differ from the one that was presented in the UniversalFile; the client is encouraged to retain the revised FileID for all future accesses to the file. The client is required to be a member of the access control list implied by access (readAccess or modifyAccess); and if access=readOnly, the client is restricted to read-only operations on the OpenFileID. The entire file is locked in lock.mode (a wait or a Lock.Failed can result). lock.ifConflict is also remembered and is used when performing certain file actions (e.g., Delete) which do not take a LockMode as an argument. Creates and opens a new file under trans. volumeID may be either a specific VolumeID or a VolumeGroupID; in the latter case, the server will choose among the volumes of the group. The initial size of the file is specified by initialSize; note that this specifies the number of data pages, and does not include any file overhead (e.g., leader page). The space is charged against owner in the owner data base; the client is required to be a member of owner's create access control list, and the allocation must not exceed owner's quota. All file properties are set to default values, which are: byteLength, highWaterMark: 0; createTime: now; readAccess: "World"; modifyAccess: "Owner" + owner's create access control list; owner: owner specified in call; stringName: empty string; version: 1. If the call is successful, returns an OpenFileID with accessRights=readWrite and lockOption = [write, fail]. The returned UniversalFile uniquely identifies the file that was created; in particular, it contains the VolumeID for the volume in which the file was actually created, even if a VolumeGroupID was presented in the call. Procedures that destroy OpenFileIDs Note: for all remaining operations, Unknown[openFileID] may be raised if: 1. The OpenFileID is no longer known to Alpine because it has been closed (either explicitly or as a result of committing or aborting the transaction). 2. The file it refers to has been deleted by this transaction, perhaps using a different OpenFileID. Breaks the association between openFileID and its file. The number of simultaneous open files permitted on one FileStore is large but not unlimited; clients are encouraged to close files that are no longer needed, particularly when referencing many files under one transaction. Note that closing a file does not terminate the enclosing transaction and does not release any locks on the file; nor does it restrict the client's ability to later re-open the file under the same transaction. First locks the entire file in update mode; then deletes the file. The file must have been opened with access=readWrite. The OpenFileID is made invalid by this procedure. Note that, like all destructive update actions, the deletion does not occur until the transaction is committed; however, subsequent attempts to access the file under this transaction will fail with Unknown[openFileID]. The owner's allocation is not credited with the deleted pages until commit time. Procedures that access open file state This may return a lock mode stronger than the one with which the file was originally opened if operations have been performed that upgrade the lock. Such operations may have been performed on either this OpenFileID or some other OpenFileID referring to the same file under the same transaction. This actually changes the file lock, so it may wait or fail according to lock.ifConflict. File locks may only be upgraded by this means; attempts to downgrade a lock are ignored. Procedures that access pages of the file Note: for operations that reference the contents of a file (data or properties), it is possible that several clients may be accessing the file concurrently under the same transaction (using the same or different OpenFileIDs). Alpine makes no attempt to prevent or adjudicate conflicting access to the same data in this situation, except to assure that reads and writes of single individual file pages and properties are atomic with respect to each other. Reads data from the pages described by pageRun of the file associated with openFileID, and puts it contiguously into client memory in the block described by pageBuffer (whose length must be consistent with pageRun.count or else OperationFailed[inconsistentDescriptor] is raised). If the entire file is not already locked in at least the mode specified by lock, sets locks in that mode on the individual pages, and upgrades the file lock to the corresponding intention mode if necessary. Writes data from client memory in the block described by pageBuffer to the pages described by pageRun of the file associated with openFileID. If the entire file is not already locked in at least the mode specified by lock, sets locks in that mode on the individual pages, and upgrades the file lock to the corresponding intention mode if necessary. The file must have been opened with access=readWrite. Explicitly sets locks on the specified pages of the file. If the specified pages of the file are locked in a mode no stronger than read, then removes those locks. It is the client's responsibility to assure consistency of any subsequent operations whose behavior depends on the data that was read under those locks. Note that locks are reference-counted and are not removed until one UnlockPages has been done for each LockPages or ReadPages previously performed on the same pages. Attempts to remove nonexistent locks or locks stronger than read are ignored without error indication. File intention locks that were set while acquiring the page locks are not released. Procedures that access properties of the file Reads the properties specified by desiredProperties, ordered as in the declaration of Property. Locks those properties as specified by lock. Currently, all properties with the exception of version are treated together with respect to locking; the version has a separate lock. Note that reading the version will prevent any other transaction that updates the file from committing, unless the version lock is later removed (by UnlockVersion). Writes the supplied properties, after first locking them in the specified mode. The version property may not be written by this means. To write the byteLength, createTime, highWaterMark, and stringName properties requires that the OpenFileID be open with access=readWrite. To write readAccess or modifyAccess requires that the client be the file's owner or a member of the create access control list for the file's owner, but does NOT require that the file be open with access=readWrite. To write owner requires that both the above conditions be satisfied, and additionally requires that the client be a member of the create access control list for the new owner; the disk space occupied by the file is credited to the old owner and charged to the new one. If there is insufficient space in the leader page to represent the new properties, OperationFailed[insufficientSpace] is raised. Note that if multiple properties are written by one call and an error occurs, some of the properties may nevertheless have been written successfully. Unlocks a read lock previously set on the version property. All comments on UnlockPages apply here also. Arranges that at transaction commit time, increment will be added to the version property, instead of 1 or 0 (depending on whether or not the transaction has performed any updates to the file). Note that the change in version number is not visible, even to the transaction that incremented it, until commit time. Returns the file's size, after setting a lock on the size property. Note that the returned value is the number of data pages, and does not include any file overhead (e.g., leader page). Changes the file's size to the new size specified, after setting an update or write lock on it. Additionally, decreasing the file's size locks the entire file in the same mode. Note that the size is the number of data pages, and does not include any file overhead (e.g., leader page). If the new size is less than the file's high water mark, sets the high water mark equal to size. Requires that the OpenFileID be open with access=readWrite. Appropriately adjusts the disk space charged to the file's owner; however, it is not required that the client be a member of the owner's create access control list. Note that allocation is consumed immediately when a file's size is increased; but when the size is decreased, the allocation is not credited with the freed pages until transaction commit time. Removes all locks no stronger than read from the file and its pages for the transaction implicit in openFileID. Attempts to remove nonexistent locks or locks stronger than read are ignored without error indication. Reference-counts referred to above are ignored. Procedures controlling the owner database Some aspects of owner database maintenance are decentralized, in that normal Alpine users may perform them. These include inspecting individual owner records and updating certain fields of owner records (these updates are restricted by access control checks that are a function of the owner). Other aspects of owner database maintenance are reserved for Alpine administrators. These include creating and deleting owner records, updating disk space quotas, and enumerating the entire set of owners. On a particular server, these operations may only be invoked by individuals who belong to that server's AlpineWheels group. Since these operations are potentially destructive, they must be explicitly "enabled" by a call to AlpineTransaction.AssertAlpineWheel. ! LockFailed {timeout}, StaticallyInvalid, Unknown {owner, transID, volumeGroupID}. Reads the properties specified by desiredProperties, ordered as in the declaration of OwnerProperty. ! AccessFailed {alpineWheel, ownerEntry}, LockFailed {timeout}, OperationFailed {ownerRecordFull, ownerRecordInUse, regServersUnavailable, totalQuotaExceeded}, StaticallyInvalid, Unknown {owner, transID, volumeGroupID}. Writes the supplied properties, leaving the others unchanged. Obtains a write lock on the owner record. (For now, WriteProperties fails by raising OperationFailed [ownerRecordInUse] if a write of the quota is requested and another transaction is concurrently changing the space in use by the given owner. Retrying may succeed.) The owner, and members of the owner's Modify access list, can update the Create access list property of an owner record. The owner, and members of the owner's Create access list can update the rootFile property of an owner record. If an update is restricted to the these properties, but the access control checks fail, then WriteProperties raises AccessFailed [ownerEntry]. The spaceInUse property is read only. If enforceTotalQuota = TRUE and properties includes quota, then WriteProperties raises OperationFailed [totalQuotaExceeded] if the total of all quotas in the owner database, including the specified update, exceeds the total number of disk pages on the volume group. On all updates, certain high-level invariants are enforced: owner access lists always have world = FALSE and owner = TRUE. An update to an access control list may raise OperationFailed [ownerRecordFull]. The system guarantees to reserve enough space for access control list storage so that each list can contain two maximum-length RNames, but does not control the division of space between lists. In order to add an element to one list it may be necessary to remove an element from another. Procedures for Alpine administrators only. These procedures require that (conversation, transID) be asserted as an Alpine Wheel. ! AccessFailed {alpineWheel}, LockFailed {timeout}, OperationFailed {duplicateOwner, ownerDatabaseFull, ownerRecordFull, totalQuotaExceeded}, StaticallyInvalid, Unknown {transID, volumeGroupID}. Creates a new owner in the specified VolumeGroup. The properties of the new owner are derived by (in effect) setting all properties to their default values, then calling WriteProperties with the specified list of properties. ! AccessFailed {alpineWheel}, LockFailed {timeout}, OperationFailed {ownerRecordInUse, spaceInUseByThisOwner}, StaticallyInvalid, Unknown {owner, transID, volumeGroupID}. Destroys an existing owner in the specified VolumeGroup. Raises OperationFailed [spaceInUseByThisOwner] if any files exist whose disk space is charged against owner. ! AccessFailed {alpineWheel}, LockFailed {timeout}, StaticallyInvalid, Unknown {owner, transID, volumeGroupID}. Stateless enumerator for the owner database. previousOwner = NIL starts an enumeration, and owner = NIL is returned at the end of an enumeration. This call locks the entire owner database in write mode to ensure consistency, which is the reason for restricting its use to Alpine administrators. ! AccessFailed {alpineWheel}, LockFailed {timeout}, Unknown {transID, volumeGroupID}. Returns aggregate information about the owner database. nOwners is the number of owners in the database, while nEntriesUsed is the number of database entries in use (deleted entries may occupy space). When nEntriesUsed = nEntries, any Create call will raise OperationFailed [ownerDatabaseFull]; a call to ReorganizeDB is required (see below) ! AccessFailed {alpineWheel}, LockFailed {timeout}, OperationFailed {insufficientSpace, ownerDatabaseFull}, Unknown {transID, volumeGroupID}. Performs a complete reorganization of the owner database, locking it in write mode and thereby making it unavailable during the reorganization. Reorganization is called for when the owner database becomes full (Create raises OperationFailed [ownerDatabaseFull]), or when the performance of owner database operations degrades due to hash collisions or deletions. The new owner database file allows up to nEntries owners; ReorganizeDB raises OperationFailed [ownerDatabaseFull] if the existing database contains more than this many owners. ReorganizeDB raises OperationFailed [insufficientSpace] if there is not enough scratch space on the volume group to perform the reorganization. ! StaticallyInvalid, Unknown {transID, volumeGroupID}. Releases any read locks held by the transaction for the owner database on volumeGroupID. Attempts to remove nonexistent locks or locks stronger than read are ignored without error indication. Procedures operating on volumes and volume groups ! Unknown {volumeGroupID}; Stateless enumerator for the on-line volume groups of this Alpine instance. previousGroup = nullVolumeGroupID starts an enumeration, and volumeGroupID = nullVolumeGroupID is returned at the end of an enumeration. For now, the transID and lock parms are ignored. The proposed usage is as follows: If transID # nullTransID and lock.mode # none then sets the specified lock on the returned volume group. Setting a read lock guarantees that the volume group will remain on-line for the remainder of the transaction. Setting a write lock excludes all other access to the volume group for the remainder of the transaction (including opening files on the volume group); this requires the caller to be an asserted AlpineWheel. ! Unknown {volumeGroupID}; Returns the list of volumes belonging to the specified volumeGroup. Locking is as for GetNextGroup. ! Unknown {volumeID}; Returns the VolumeGroupID of the volume group containing the specified volume. Locking is as for GetNextGroup. Ê – "cedar" style˜codešœ ™ Kšœ Ïmœ1™Kšœžœ$˜8Kšœžœ&˜˜¤KšœÖ™Ö—K˜—šœ&™&K˜šŸœž œ+˜FKšžœ8˜?Kšžœ%˜,K˜—šŸ œž œ+˜@Kšžœ,˜3Kšžœ%˜,K˜—šŸœž œ+˜EKšžœ0˜7Kšžœ%˜,K˜—šŸ œž œ+˜CKšžœ,˜3Kšžœ%˜,K˜Kšœ¦™¦K™—šŸ œž œ>žœžœD˜ÃK˜Kšœ²™²K™—šŸœž œ+˜GKšžœ:˜AKšžœ%˜,K˜—šŸœž œ+˜IKšžœ>˜EKšžœ%˜,K˜—KšŸœž œPžœžœ8˜ÏK˜—šœ(™(K˜KšœÆ™ÆK™šŸ œž œPžœ9žœU˜€K˜Kšœæ™æK™—šŸ œž œmžœžœc˜ŽK™Kšœ’™’K™—šŸ œž œQžœžœD˜ÒK™Kšœ9™9K™—šŸ œž œ>žœžœ8˜µK™Kšœã™ã—K™—šœ-™-K˜šŸœž œ]˜vKšžœ2˜9KšžœD˜KK™Kšœ¸™¸K™—šŸœž œVžœžœc˜üK™Kšœ†™†Kšœ¨žœÂ™íKšœ–™–K™—šŸ œž œ,žœžœ˜}K™Kšœh™hK™—š Ÿœž œ7žœžœžœžœF˜ÏK™Kšœ¸™¸K™—šŸœž œ=˜OKšžœ+˜2Kšžœ1˜8K™Kšœ¹™¹K™—šŸœž œOžœžœc˜íK™Kšœœ™œKšœœ™œKšœå™åK˜—šŸ œž œ,žœžœ8˜¢K™Kšœ‰™‰K™——™)Jšœ¥™¥JšœÑ™ÑLšœžœ%˜:šŸœž œ|žœ8žœD˜¤JšœS™SJšœd™d—š Ÿœž œ†žœžœžœc˜ºJšœÛ™ÛJšœÊ™ÊJšœ™Jšœžœî™‰Jšœcžœ žœ™zJšœð™ðJ™——J˜šœ™š Ÿ œž œ†žœžœ>žœc˜ÕJšœÂ™ÂJšœá™á—šŸ œž œVžœžœc˜ùJšœª™ªJšœ¥™¥—šŸ œž œ„žœJžœR˜ÂJšœo™oJšœ>žœ$žœ¿™§—š Ÿœž œEžœ#ž œTžœ?˜µJšœU™UJšœ7™7Jšœ ™ Jšœ™—š Ÿœž œNž œžœžœP˜ñJšœ™Jšœª™ª——˜šŸ œž œDžœžœ8˜½Jšœ6™6Jšœ¿™¿—K™—™1šŸ œž œWžœ9žœ$˜ÙJšœ™JšœÔ™ÔJšœü™ü—Lšœ žœ˜.šŸœž œWžœ/žœ$˜ËJšœ™Jšœc™c—šŸœž œMžœ9žœ$˜ÔJšœ™Jšœn™n—K™——K˜Kšžœ˜K™—…—/f„t