263 lines
11 KiB
Plaintext
263 lines
11 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
|
|
{
|
|
AccessDenied,
|
|
AlreadyExists,
|
|
BadArguments,
|
|
ContractNotSupported,
|
|
DirectoryNotEmpty,
|
|
DoesNotExist,
|
|
NotFound,
|
|
NotImplemented,
|
|
}
|
|
|
|
// enumeration of the existing node types found in the namespace
|
|
// implementation and the filesystem
|
|
public enum NodeType
|
|
{
|
|
Dir,
|
|
File,
|
|
IoMemory,
|
|
ServiceProvider,
|
|
SymLink,
|
|
}
|
|
|
|
// a REP struct used to return responses to find or notify.
|
|
public rep struct FindResponse : ITracked
|
|
{
|
|
public char[]! in ExHeap Path; // short name within a directory
|
|
public NodeType Type; // its type
|
|
}
|
|
|
|
public contract DirectoryServiceContract : ServiceContract
|
|
{
|
|
|
|
// attempt to bind to a 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(ErrorCode code,
|
|
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,
|
|
NotifyContract.Imp:Start! imp);
|
|
out message AckNotify();
|
|
out message NakNotify(NotifyContract.Imp:Start! imp,
|
|
ErrorCode error);
|
|
|
|
// Find path and return all elements matching pattern
|
|
in message Find(char[]! in ExHeap path,char[]! in ExHeap pattern);
|
|
out message AckFind (FindResponse[]! in ExHeap results);
|
|
out message NakFind(ErrorCode error);
|
|
|
|
// Find path and return all elements matching pattern A
|
|
// AND notify of all changes over the imp endpoint supplied.
|
|
// this should solve any potential race conditions if
|
|
in message FindAndNotify(char[]! in ExHeap path,
|
|
char[]! in ExHeap pattern,
|
|
NotifyContract.Imp:Start! imp);
|
|
out message AckFindAndNotify (FindResponse[]! in ExHeap results);
|
|
out message NakFindAndNotify(NotifyContract.Imp:Start! imp,
|
|
ErrorCode error);
|
|
|
|
// given a path return its nodetype and if meaningful its length
|
|
in message Attributes(char []! in ExHeap path);
|
|
out message AckAttributes(NodeType type, long size);
|
|
out message NakAttributes(ErrorCode code);
|
|
|
|
// given a path return the associated ACL if present
|
|
in message QueryACL(char []! in ExHeap path,
|
|
byte[]! in ExHeap permission);
|
|
out message AckQueryACL(byte[]! in ExHeap acl);
|
|
out message NakQueryACL(ErrorCode code);
|
|
|
|
|
|
// 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);
|
|
|
|
// 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);
|
|
|
|
// 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);
|
|
|
|
// 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);
|
|
|
|
// 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.Imp:Ready! imp);
|
|
out message AckCreateAndBindFile();
|
|
out message NakCreateAndBindFile(ErrorCode code,
|
|
FileContract.Imp:Ready imp);
|
|
|
|
// 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);
|
|
|
|
// for the given path and permission, return the associated ACL if present
|
|
|
|
in message StoreACL(char []! in ExHeap fileName,
|
|
byte[]! in ExHeap permission,
|
|
byte[]! in ExHeap acl);
|
|
out message AckStoreACL();
|
|
out message NakStoreACL(ErrorCode code);
|
|
|
|
// 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);
|
|
|
|
// delete symlink node at linkPath
|
|
in message DeleteLink(char []! in ExHeap linkPath);
|
|
out message AckDeleteLink();
|
|
out message NakDeleteLink(ErrorCode code);
|
|
|
|
// 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.
|
|
out message NakBindReparse(char[]! in ExHeap path,
|
|
char[]! in ExHeap rest,
|
|
bool linkFound,
|
|
ServiceContract.Exp:Start! exp);
|
|
|
|
out message NakNotifyReparse(char[]! in ExHeap path,
|
|
char[]! in ExHeap rest,
|
|
bool linkFound,
|
|
NotifyContract.Imp:Start imp);
|
|
|
|
out message NakFindAndNotifyReparse(char[]! in ExHeap path,
|
|
char[]! in ExHeap rest,
|
|
bool linkFound,
|
|
NotifyContract.Imp:Start imp);
|
|
|
|
out message NakFindReparse(char[]! in ExHeap path,
|
|
char[]! in ExHeap rest,
|
|
bool linkFound);
|
|
|
|
out message NakRegisterReparse(char[]! in ExHeap path,
|
|
char[]! in ExHeap rest,
|
|
ServiceProviderContract.Imp:Start imp);
|
|
|
|
out message Success();
|
|
|
|
////////////////////////////////////////////////////////
|
|
// State Machine
|
|
////////////////////////////////////////////////////////
|
|
|
|
override state Start: one {
|
|
Success! -> Ready;
|
|
}
|
|
state Ready: one
|
|
{
|
|
Bind? -> (AckBind!
|
|
or NakBind!
|
|
or NakBindReparse!
|
|
) -> Ready;
|
|
|
|
Find? -> (AckFind!
|
|
or NakFind!
|
|
or NakFindReparse!
|
|
) -> Ready;
|
|
|
|
FindAndNotify? -> (AckFindAndNotify!
|
|
or NakFindAndNotify!
|
|
or NakFindAndNotifyReparse!
|
|
) -> Ready;
|
|
|
|
|
|
Notify? -> (AckNotify!
|
|
or NakNotify!
|
|
or NakNotifyReparse!
|
|
) -> Ready;
|
|
|
|
Register? -> (AckRegister!
|
|
or NakRegister!
|
|
or NakRegisterReparse!
|
|
) -> Ready;
|
|
|
|
CreateDirectory? -> (AckCreateDirectory!
|
|
or NakCreateDirectory!
|
|
) -> Ready;
|
|
|
|
DeleteDirectory? -> (AckDeleteDirectory!
|
|
or NakDeleteDirectory!
|
|
) -> Ready;
|
|
|
|
CreateFile? -> (AckCreateFile!
|
|
or NakCreateFile!
|
|
) -> Ready;
|
|
|
|
CreateAndBindFile? -> (AckCreateAndBindFile!
|
|
or NakCreateAndBindFile!
|
|
) -> Ready;
|
|
|
|
DeleteFile? -> (AckDeleteFile!
|
|
or NakDeleteFile!
|
|
) -> Ready;
|
|
|
|
Attributes? -> (AckAttributes!
|
|
or NakAttributes!
|
|
) -> Ready;
|
|
|
|
QueryACL? -> (AckQueryACL! or NakQueryACL!) -> Ready;
|
|
StoreACL? -> (AckStoreACL! or NakStoreACL!) -> Ready;
|
|
|
|
CreateLink? -> (AckCreateLink!
|
|
or NakCreateLink!
|
|
) -> Ready;
|
|
|
|
DeleteLink? -> (AckDeleteLink!
|
|
or NakDeleteLink!
|
|
) -> Ready;
|
|
}
|
|
}
|
|
}
|