singrdk/base/Contracts/Directory.Contracts/DirectoryServiceContract.sg

332 lines
14 KiB
Plaintext

////////////////////////////////////////////////////////////////////////////////
//
// Microsoft Research Singularity
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// File: DirectoryServiceContract.sg
//
using Microsoft.SingSharp;
using Microsoft.Singularity.Channels;
namespace Microsoft.Singularity.Directory
{
// enumeration of possible errors reported by any operation
public enum ErrorCode : uint
{
NoError = 0,
AccessDenied = 1,
AlreadyExists = 2,
BadArguments = 3,
ContractNotSupported = 4,
DirectoryNotEmpty = 5,
NotFound = 6,
ChannelClosed = 7,
Unsatisfiable = 8,
NotImplemented = 9,
NotSupported = 10,
CapacityReached = 11,
InsufficientResources = 12,
DirectoryFull = 13,
NotDirectory = 14,
NotLink = 15,
NotProvider = 16,
NotFile = 17,
IsOpen = 18,
Unknown = 99,
}
// enumeration of the existing node types found in the namespace
// implementation and the filesystem
public enum NodeType
{
Directory = 1,
File = 2,
IoMemory = 4,
ServiceProvider = 8,
SymLink = 16,
BadNode = 32,
}
// a REP struct used to return responses to find or notify.
public rep struct EnumerationRecords : ITracked
{
public char[]! in ExHeap Path; // short name within a directory
public NodeType Type; // its type
}
public contract DirectoryServiceContract : ServiceContract
{
// REPARSE MESSAGES
// used for 2 different scenarios: DirectoryProvider and SymLink traversal
// DirectoryProvider:
// path=new directoryProvider to bind to to continue traversal
// rest=suffix(P): the remainder of the initial path not yet parsed.
// SymLink
// path=contents of the symbolic link
// rest=suffix(P): the remainder of the initial path not yet parsed.
// attempt to bind to an service exp endpoint
in message Bind(char[]! in ExHeap path,
ServiceContract.Exp:Start! exp);
out message AckBind();
// attempt to return unused endpoint if possible
out message NakBind(ServiceContract.Exp:Start exp,
ErrorCode code);
out message NakBindReparse(char[]! in ExHeap path,
char[] in ExHeap rest,
bool linkFound,
ServiceContract.Exp:Start! exp);
// Find path and notify caller of any changes matching pattern over
// the imp endpoint supplied.
in message Notify(char[]! in ExHeap path,
char[]! in ExHeap pattern,
bool sendExisting,
NotifyContract.Imp:Start! imp);
out message AckNotify();
out message NakNotify(NotifyContract.Imp:Start! imp,
ErrorCode error);
out message NakNotifyReparse(char[]! in ExHeap path,
char[]! in ExHeap rest,
bool linkFound,
NotifyContract.Imp:Start imp);
// Enumerate the contents of the current directory
in message BeginEnumeration();
in message ReadEnumeration();
in message EndEnumeration();
out message EnumerationEntries (EnumerationRecords[]! in ExHeap results, bool moreEntries);
out message EnumerationTerminated(ErrorCode error);
// given a path return its nodetype and if meaningful its length
in message GetAttributes(char []! in ExHeap path);
out message AckGetAttributes(NodeType type, long size);
out message NakGetAttributes(ErrorCode code);
out message NakGetAttributesReparse(char[]! in ExHeap path,
char[]! in ExHeap rest,
bool linkFound);
// given a path return the associated ACL if present
in message QueryACL(char []! in ExHeap path, bool effective);
out message AckQueryACL(char[] in ExHeap nodePattern, char[] in ExHeap descendantPattern);
out message NakQueryACL(ErrorCode code);
out message NakQueryACLReparse(char[]! in ExHeap path,
char[]! in ExHeap rest,
bool linkFound);
// Greater permissions needed for ops below
// register a service's name serviceProvider endpoint with the SDS
in message Register(char[]! in ExHeap path,
ServiceProviderContract.Imp:Start! imp);
out message AckRegister();
out message NakRegister(ServiceProviderContract.Imp:Start imp,
ErrorCode error);
out message NakRegisterReparse(char[]! in ExHeap path,
char[]! in ExHeap rest,
bool linkFound,
ServiceProviderContract.Imp:Start! imp);
// Deregister a service's name from the SDS
in message Deregister(char[]! in ExHeap path);
out message AckDeregister(ServiceProviderContract.Imp:Start! imp); // return deregistered endpoint
out message NakDeregister(ErrorCode error);
out message NakDeregisterReparse(char[]! in ExHeap path,
char[]! in ExHeap rest,
bool linkFound);
// create dirName within the current directory
// the current directory is the one bound on this channel
in message CreateDirectory(char []! in ExHeap dirName);
out message AckCreateDirectory();
out message NakCreateDirectory(ErrorCode code);
out message NakCreateDirectoryReparse(char[]! in ExHeap path,
char[]! in ExHeap rest,
bool linkFound);
// delete dirName within the current directory
// the current directory is the one bound on this channel
in message DeleteDirectory(char []! in ExHeap dirName);
out message AckDeleteDirectory();
out message NakDeleteDirectory(ErrorCode code);
out message NakDeleteDirectoryReparse(char[]! in ExHeap path,
char[]! in ExHeap rest,
bool linkFound);
// create file within the current directory
// the current directory is the one bound on this channel
// file creation only applies to the FS
in message CreateFile(char []! in ExHeap fileName);
out message AckCreateFile();
out message NakCreateFile(ErrorCode code);
out message NakCreateFileReparse(char[]! in ExHeap path,
char[]! in ExHeap rest,
bool linkFound);
// create and "open" or bind to fileName within the current directory
// the current directory is the one bound on this channel
// this is common enough pattern to supply an optimization
in message CreateAndBindFile(char []! in ExHeap fileName,
FileContract.Exp:Start! exp);
out message AckCreateAndBindFile();
out message NakCreateAndBindFile(FileContract.Exp:Start! exp,
ErrorCode code);
// delete fileName within the current directory
// the current directory is the one bound on this channel
in message DeleteFile(char []! in ExHeap fileName);
out message AckDeleteFile();
out message NakDeleteFile(ErrorCode code);
out message NakDeleteFileReparse(char[]! in ExHeap path,
char[]! in ExHeap rest,
bool linkFound);
// for the given path and permission, return the associated ACL if present
in message StoreACL(char []! in ExHeap fileName,
char[] in ExHeap nodePattern, char[] in ExHeap descendantPattern);
out message AckStoreACL();
out message NakStoreACL(ErrorCode code);
out message NakStoreACLReparse(char[]! in ExHeap path,
char[]! in ExHeap rest,
bool linkFound);
// create a symlink node at linkPath with value linkValue
// Upon traversal linkPath will be returned to client
// it is up to the client to interpret and re-submit bind
// see reparse messages below.
in message CreateLink(char []! in ExHeap linkPath,
char []! in ExHeap linkValue );
out message AckCreateLink();
out message NakCreateLink(ErrorCode code);
out message NakCreateLinkReparse(char[]! in ExHeap path,
char[]! in ExHeap rest,
bool linkFound);
// delete symlink node at linkPath
in message DeleteLink(char []! in ExHeap linkPath);
out message AckDeleteLink();
out message NakDeleteLink(ErrorCode code);
out message NakDeleteLinkReparse(char[]! in ExHeap path,
char[]! in ExHeap rest,
bool linkFound);
// Get symlink value
in message GetLinkValue(char []! in ExHeap linkPath);
out message AckGetLinkValue(char []! in ExHeap linkPath);
out message NakGetLinkValue(ErrorCode code);
out message NakGetLinkValueReparse(char[]! in ExHeap path,
char[]! in ExHeap rest,
bool linkFound);
out message Success();
////////////////////////////////////////////////////////
// State Machine
////////////////////////////////////////////////////////
override state Start: one {
Success! -> Ready;
}
state Enumerate : one {
EnumerationTerminated! -> Ready;
EnumerationEntries! -> EnumerateAck;
}
state EnumerateAck : one {
ReadEnumeration? -> Enumerate;
EndEnumeration? -> Ready;
}
state Ready: one
{
Bind? -> (AckBind!
or NakBind!
or NakBindReparse!
) -> Ready;
BeginEnumeration? -> Enumerate;
CreateAndBindFile? -> (AckCreateAndBindFile!
or NakCreateAndBindFile!
) -> Ready;
CreateDirectory? -> (AckCreateDirectory!
or NakCreateDirectory!
or NakCreateDirectoryReparse!
) -> Ready;
CreateFile? -> (AckCreateFile!
or NakCreateFile!
or NakCreateFileReparse!
) -> Ready;
CreateLink? -> (AckCreateLink!
or NakCreateLink!
or NakCreateLinkReparse!
) -> Ready;
DeleteDirectory? -> (AckDeleteDirectory!
or NakDeleteDirectory!
or NakDeleteDirectoryReparse!
) -> Ready;
DeleteFile? -> (AckDeleteFile!
or NakDeleteFile!
or NakDeleteFileReparse!
) -> Ready;
DeleteLink? -> (AckDeleteLink!
or NakDeleteLink!
or NakDeleteLinkReparse!
) -> Ready;
Deregister? -> (AckDeregister!
or NakDeregister!
or NakDeregisterReparse!
) -> Ready;
GetAttributes? -> (AckGetAttributes!
or NakGetAttributes!
or NakGetAttributesReparse!
) -> Ready;
GetLinkValue? -> (AckGetLinkValue!
or NakGetLinkValue!
or NakGetLinkValueReparse!
) -> Ready;
Notify? -> (AckNotify!
or NakNotify!
or NakNotifyReparse!
) -> Ready;
QueryACL? -> (AckQueryACL!
or NakQueryACL!
or NakQueryACLReparse!
) -> Ready;
Register? -> (AckRegister!
or NakRegister!
or NakRegisterReparse!
) -> Ready;
StoreACL? -> (AckStoreACL!
or NakStoreACL!
or NakStoreACLReparse!
) -> Ready;
}
}
}