AMS Extensions
Version 5.0
Andrew Hanushevsky
Stanford Linear Accelerator Center
10/27/99
Acknowledgements
Urs Bertschinger, Objectivity Inc.
for co-designing the initial oofs interface and modifying AMS v4 to use it.
Karl Quackenbush, Objectivity Inc.
for suggested improvements and modifying AMS v5 to use the initial interface.
Satya Pulavarthi, Objectivity Inc.
for co-designing the final oofs interface and modifying AMS v5.2 to use the final interface.
Dan Treachler, Objectivity Inc.
for numerous usability suggestions and designing the software packaging.
Marcin Nowak, CERN
for invaluable debugging assistance and helpful modifications.
1 Introduction
*1.1 Acronyms
*2.1 Common Definitions
*2.1.1 Constants
*2.1.2 Limits
*2.1.3 Data Types
*2.1.4 Classes
*2.1.4.1 The oofsError Class
*2.2 Client-Side Definitions
*2.2.1 Constants
*2.2.2 Data Types
*2.2.3 Classes
*2.2.3.1 The oofsAMSClientSecurity Class
*2.2.4 Opaque Information Interface
*2.3 Server-Side Definitions
*2.3.1 Constants
*2.3.2 Limits
*2.3.3 Data Types
*2.3.4 Classes
*2.3.4.1 The oofsFileSystemDesc Class
*2.3.4.2 The oofsFile Class
*2.3.4.3 The oofsDirectory Class
*2.4 Multi-Threading Definitions
*2.4.1 The CCriticalSection Class
*2.4.2 The CUseCriticalSection Class
*2.4.3 The CSemaphore Class
*2.4.4 The CThreadStartData Class
*2.4.5 The CThread Class
*3 oofs Interface Definition
*3.1 oofsGetFileSystem()
*3.2 oofsFileSystemDesc Class Methods
*3.2.1 exists()
*3.2.2 getSecurityToken()
*3.2.3 openDir()
*3.2.4 openFile()
*3.2.5 remove()
*3.2.6 rename()
*3.3 oofsDirectory Class Methods
*3.3.1 close()
*3.3.2 nextEntry()
*3.3.3 open()
*3.4 oofsError Class Methods
*3.4.1 getErrorInfo()
*3.4.2 setErrorInfo()
*3.5 oofsFile Class Methods
*3.5.1 close()
*3.5.2 getmode()
*3.5.3 getsize()
*3.5.4 open()
*3.5.5 read()
*3.5.6 sync()
*3.5.7 truncate()
*3.5.8 write()
*4 Generic Authentication Protocol
*4.1 Application Steps in GAP
*4.2 OCSK Steps in GAP
*4.3 AMS Steps in GAP
*4.4 Security Interface Definition
*4.4.1 oofs_createSecurityContext()
*4.4.1.1 getCredentials()
*5 Opaque Information Protocol
*5.1 Application Steps in OIP
*5.2 OCSK Steps in OIP
*5.3 AMS Steps in OIP
*5.3.1 oofs_set_info()
*6 Defer Request Protocol
*6.1 AMS Steps in DRP
*6.2 OCSK Steps in DRP
*7 Request Redirection Protocol
*7.1 AMS Steps in RRP
*7.2 OCSK Steps in RRP
*8 Appendix A
*8.1 Real Time Record Format
*8.1.1 Record Types
*8.1.2 Variable Names
*8.1.3 Variable Name by Record Type
*This document describes Advanced Multithreaded Server (AMS) extensions providing:
The relationships between these components are shown in the following figure.
Major changes occur in the AMS. Prior to the changes, the AMS was distributed as a single module. The new AMS is distributed as two linkable components:
These two components are then dynamically linked to two site selectable components:
A functional AMS is built by linking the appropriate four components. The default AMS is normally distributed as an executable module along with a shared librry that uses the native Unix File System (UFS) and provides a null security service.
The client-side components are relatively straightforward. The Objectivity Kernel internally handles DRP and RRP. Client-supplied programs provide authentication information through a dynamically linked standard interface. Hence, the client-side kernel pulls authentication information. Opaque information is supplied by the application through a standard kernel based-interface. Hence, opaque information is pushed by the application. In either case, applications implicitly use the GAP and OIP components and no substantial changes are required for the client-side Kernel.
Acronyms
AMS
Advanced Multithreaded ServerAMSC Advanced Multithreaded Server Collective
APID Autonomous Partition Identifier
DRP Defer Request Protocol
FDID Federated Database Identifier
GAP Generic Authentication Protocol
OCSK Objectivity Client-Side Kernel
OOFS Object Open File System
OIP Opaque Information Protocol
RRP Request Redirect Protocol
SO Security Object of class oofsAMSSecurityCredentials supplied by the client
ST
Security Token of class oofsAMSSecurityIdentifiers returned by the AMS// Current version of the oofs interfaces
#define OOFS_FILE_SYSTEM_DESC_VERSION 1
// Valid return values from oofs that return an integer
#define OOFS_OK 0 // Return code -> All is well
#define OOFS_ERROR -1 // Return code -> Error occurred
// Longest error message string returned (including trailing null)
#define OOFS_MAX_ERROR_LEN (255+1)
// Maximum number of bytes of opaque information that can be set
#define OOFS_MAX_INFO_LEN 4096
// Maximum number of bytes of security information that can be set
#define OOFS_MAX_SECURITY_BUFFER_LEN 4096
struct oofsBuffer // Generic buffer definition
{ ooUInt32 size;
char *data;
void clear() {size = 0; data = NULL;}
oofsBuffer() {clear();}
};
struct oofsErrorStruct // Error information structure
{ ooUInt32 code;
char message[OOFS_MAX_ERROR_LEN];
void clear() {code = 0; message[0] = ‘\0’;}
oofsErrorStruct() {clear();}
};
struct oofsSecurityStruct
{ char sectype[4];
ooUInt32 size;
char buffer[OOFS_MAX_SECURITY_BUFFER_LEN];
void clear() {size = 0; buffer[0] = ‘\0’;
sectype[0]=’N’; sectype[1]=’O’;
sectype[2]=’N’; sectype[3]=’E’;}
oofsSecurityStruct() {clear();}
class oofsError
{protected:
oofsErrorStruct ErrorInfo;
public:
int getErrorInfo() {return ErrorInfo.code;}
int getErrorInfo(oofsErrorStruct &ErrorParm)
{strcpy(ErrorParm.message, ErrorInfo.message);
ErrorParm.code = ErrorInfo.code;
Return ErrorInfo.code;
}
int setErrorInfo(const ooUint32 code, const char *message)
{strcpy(ErrorInfo.message, message);
ErrorInfo.code = code;
Return code;
}
void clear() { ErrorInfo.clear(); }
oofsError() { }
oofsError(const oofsErrorStruct &errorParm)
{setErrorInfo(errorParm.code, errorParm.message);}
oofsError& operator = (const oofsError &error)
{setErrorInfo(error.ErrorInfo.code,
error.ErrorInfo.message);
return *this;
}
}
// Operation class codes when calling oofs_getCredentials()
#define OOFS_DIRS 0x0100 // Directory operations
#define OOFS_META 0x0200 // Metadata operations
#define OOFS_MISC 0x0400 // Miscellaneous
#define OOFS_OPCL 0x0800 // Open/close operations
#define OOFS_RWTS 0x1000 // Read/write operations
// Operation codes when calling oofs_getCredentials()
#define OOFS_CLOSE 0x01|OOFS_OPCL // OPCL: oofs_close()
#define OOFS_CLOSEDIR 0x02|OOFS_DIRS // Dirs: not used
#define OOFS_EXISTS 0x03|OOFS_MISC // Misc: oofs_exists()
#define OOFS_GETSIZE 0x04|OOFS_MISC // Misc: oofs_getsize()
#define OOFS_GETMODE 0x05|OOFS_MISC // Misc: oofs_getmode()
#define OOFS_OPEN 0x06|OOFS_OPCL // OPCL: oofs_open()
#define OOFS_OPENDIR 0x07|OOFS_DIRS // Dirs: oofs_opendir()
#define OOFS_READ 0x08|OOFS_RWTS // RWTS: oofs_read()
#define OOFS_READDIR 0x09|OOFS_DIRS // Dirs: not used
#define OOFS_REMOVE 0x0a|OOFS_META // Meta: oofs_remove()
#define OOFS_RENAME 0x0b|OOFS_META // Meta: oofs_rename()
#define OOFS_SYNC 0x0c|OOFS_RWTS // RWTS: oofs_sync()
#define OOFS_TRUNCATE 0x0d|OOFS_RWTS // RWTS: oofs_truncate()
#define OOFS_WRITE 0x0e|OOFS_RWTS // RWTS: oofs_write()
// Current version of the oofs interfaces
#define OOFS_SEC_SYSTEM_DESC_VERSION 1
typedef oofsSecurityStruct oofsAMSSecurityIdentifiers;
typedef oofsSecurityStruct oofsAMSSecurityCredentials;
enum oofsSetInfoUse
{
oofsSetInfoAlways,
oofsSetInfoOnce
};
class oofsAMSClientSecurity
{
protected:
oofsError error;
public:
oofsAMSClientSecurity() { }
int getErrorInfo() {return error.getErrorInfo();}
int getErrorInfo(oofsErrorStruct &errorParm)
{return error.getErrorInfo(errorParm);}
int getVersion()
{return OOFS_SEC_SYSTEM_DESC_VERSION;}
virtual int getCredentials(ooUInt32 operation, // In
const char *pathname, // In
oofsAMSSecurityCredentials &cred) = 0; // Out
}
// Routine to create the oofsAMSClient Security object
oofsAMSClientSecurity *oofs_createSecurityContext
(const struct sock_addr_in &netaddr,
const oofsAMSSecurityIdentifiers &secids);
}
// Routine to delete the oofsAMSClient Security object
//
void oofs_deleteSecurityContext(oofsAMSClientSecurity *sec);
int oofs_set_info(const char *info,
const int infolen,
oofsSetInfoUse flags);
// Parameter to the oofs_Open() function to set access mode
#define OOFS_S_IRWXU 0000700 // Owner: read, write, execute perm
#define OOFS_S_IRUSR 0000400 // Owner: read permission
#define OOFS_S_IWUSR 0000200 // Owner: write permission
#define OOFS_S_IXUSR 0000100 // Owner: execute/search permission
#define OOFS_S_IRWXG 0000070 // Group: read, write, execute perm
#define OOFS_S_IRGRP 0000040 // Group: read permission
#define OOFS_S_IWGRP 0000020 // Group: write permission
#define OOFS_S_IXGRP 0000010 // Group: execute/search permission
#define OOFS_S_IRWXO 0000007 // Other: read, write, execute perm
#define OOFS_S_IROTH 0000004 // Other: read permission
#define OOFS_S_IWOTH 0000002 // Other: write permission
#define OOFS_S_IXOTH 0000001 // Other: execute/search permission
// Parameter to the oofs_Open() function to set access type
#define OOFS_O_RDONLY 0 // open read/only
#define OOFS_O_WRONLY 1 // open write/only
#define OOFS_O_RDWR 2 // open read/write
#define OOFS_O_CREAT 0x100 // open creating the file
// Longest filename returned by interface (including trailing null)
#define OOFS_MAX_FILE_NAME_LEN (1024+1)
typedef char oofsFileNameBuf[OOFS_MAX_FILE_NAME_LEN];
typedef ooInt32 oofsFileCreateMode;
typedef ooInt32 oofsFileOpenMode;
typedef ooInt32 oofsXferSize;
typedef oofsBuffer oofsClientCredentials;
typedef oofsBuffer oofsOpaqueInfo;
typedef oofsSecurityStruct oofsSecurityToken;
enum oofsFileExistance
{
oofsFileExistNo,
oofsFileExistIsFile,
oofsFileExistIsDirectory
};
struct oofsCredentials // Credentials passed to oofs
{ struct sockaddr ClientHostAddress; // <- getpeername()
oofsClientCredentials ClientCredentials;
};
struct oofsFileOffset // 64-bit file offset
{ ooUInt32 high_offset;
ooUInt32 low_offset;
void clear() {high_offset = 0; low_offset = 0;}
oofsFileOffset() {clear();}
};
class oofsFileSystemDesc
{
public:
int getVersion() {return OOFS_FILE_SYSTEM_DESC_VERSION;}
virtual int getSecurityToken(oofsSecurityToken &,
struct sockaddr &,
oofsError &out_error) = 0;
/********** File Functions **********/
virtual oofsFile *openFile(const char *FileName,
oofsFileOpenMode openMode,
oofsFileCreateMode createMode,
oofsError &out_error,
oofsCredentials *p_cred=0,
oofsOpaqueInfo *p_info=0) = 0;
/********** Directory Functions **********/
virtual oofsDirectory *openDir(const char *directoryPath,
oofsError &out_error,
oofsCredentials *p_cred=0) = 0;
/********** Miscellaneous Functions **********/
virtual int exists(const char *fileName,
oofsFileExistance &exists_flag,
oofsError &out_error,
oofsCredentials *p_cred) = 0;
virtual int remove(const char *fileName,
oofsError &out_error,
oofsCredentials *p_cred) = 0;
virtual int rename(const char *oldFileName,
const char *newFileName,
oofsError &out_error,
oofsCredentials *p_cred) = 0;
// destruct called at AMS exit
void (*destruct)(); // can set to 0, to not destruct
oofsFileSystemDec() { destruct = NULL; }
};
// Init & return -> oofsFileSystemDesc
oofsFileSystemDesc *oofsGetFileSystem(oofsFileSystemDesc *native_fs);
class oofsFile : virtual public oofsError
{protected:
oofsError error;
public:
oofsFile(){ }
virtual ~oofsFile() { };
virtual int getErrorInfo()
{return error.getErrorInfo();}
virtual int getErrorInfo(oofsError &out_error)
{out_error = error; return error.getErrorInfo();}
/********** Basic File Functions **********/
virtual int open(const char *fileName,
oofsFileOpenMode openMode,
oofsFileCreateMode createMode,
const oofsCredentials *credentials = 0,
const oofsOpaqueInfo *opaqueInfo = 0)
= 0;
virtual int close(oofsCredentials *credentials = 0) = 0;
virtual oofsXferSize read(oofsFileOffset fileOffset,
char *buffer,
oofsXferSize buffer_size,
const oofsCredentials *credentials = 0)
= 0;
virtual oofsXferSize write(oofsFileOffset fileOffset,
const char *buffer,
oofsXferSize buffer_size,
const oofsCredentials *credentials = 0)
= 0;
virtual int sync (const oofsCredentials *credentials = 0)
= 0;
virtual int truncate(oofsFileOffset fileOffset,
const oofsCredentials *credentials= 0)
= 0;
virtual int getSize(oofsFileOffset &fileOffset,
const oofsCredentials *credentials = 0)
= 0;
virtual int getMode(oofsFileCreateMode &CreateMode,
const oofsCredentials *credentials = 0)
= 0;
}; // class oofsFile
class oofsDirectory
{protected:
oofsError error;
public:
oofsDirectory() { }
virtual ~oofsDirectory();
virtual int getErrorInfo()
{return error.getErrorInfo();}
virtual int getErrorInfo(oofsError &out_error)
{out_error = error; return error.getErrorInfo();}
/********** Basic Directory Functions **********/
virtual int open(const char *dir,
const oofsCredentials *creds = 0)
= 0;
virtual const char *nextEntry(const oofsCredentials *creds = 0)
= 0;
virtual int close(const oofsCredentials *creds = 0)
= 0;
}; // class oofsDirectory
class CCriticalSection
{
private:
pthread_mutex_t cs ;
public:
CCriticalSection()
{pthread_mutex_init(&cs , 0);}
~CCriticalSection()
{pthread_mutex_destroy(&cs);}
void enter() {pthread_mutex_lock(&cs);}
void leave() {pthread_mutex_unlock(&cs);}
};
class CUseCriticalSection
{
private :
CCriticalSection &cs;
public :
CUseCriticalSection(CCriticalSection &in_cs) : cs(in_cs)
{cs.enter();}
~ CUseCriticalSection( ) {cs.leave();}
};
class CSemaphore
{
private:
sem_t h_semaphore;
public :
CSemaphore()
{if ( sem_init(&h_semaphore , 0, 0))
{throw "sem_init() failed", errno;}
}
~CSemaphore()
{if (sem_destroy(&h_semaphore))
{throw "sem_destroy() failed", errno;}
}
void increment()
{if (sem_post(&h_semaphore))
{throw "sem_post() failed", errno;}
}
void wait()
{if ( sem_wait (&h_semaphore))
{throw "sem_post() failed", errno;}
}
};
typedef void *CTHREAD_RETURN_TYPE;
class CThreadStartData
{
private:
void *real_data;
int exit_code;
public:
CThreadStartData()
{real_data = 0; exit_code = 0xBADF00D;}
void *getData() {return real_data;}
void setData( void *in_data )
{real_data = in_data;}
CTHREAD_RETURN_TYPE setExitCode(int in_exit_code)
{exit_code = in_exit_code;
return (void *) &exit_code;
}
int getExitCode()
{return exit_code;}
};
typedef CTHREAD_RETURN_TYPE (*CTHREAD_START_FUNC) (CThreadStartData &);
class CThread
{
private:
pthread_t h_thread;
int exit_status;
CThreadStartData threadData;
CTHREAD_START_FUNC p_start_func;
public:
CThread()
{p_start_func = 0; h_thread = 0; exit_status = - 1;}
void close(){ }
~CThread() {close();}
int isHandleOpen()
{if ( h_thread )return ~ 0; return 0;}
static void *our_start_func(void *in_p_this)
{CThread *p_this = (CThread *)in_p_this;
return p_this->p_start_func(p_this->threadData);
}
int createThread(CTHREAD_START_FUNC in_p_start_func, void *arg,
int create_suspended = FALSE, size_t max_stack_size = 0)
{threadData.setData(arg);
p_start_func = in_p_start_func;
int rc;
pthread_attr_t attr;
pthread_attr_init(&attr);
if (max_stack_size > 0)
pthread_attr_setstacksize (&attr, max_stack_size);
rc = pthread_create(&h_thread, &attr,
our_start_func,(void *)this);
pthread_attr_destroy(&attr);
return rc;
}
int getExitCode(int &rc)
{rc = threadData.getExitCode();
return 0;
}
int resume(){return 0;}
int wait()
{int rc;
void *p_status;
rc = pthread_join(h_thread, &p_status);
return rc;
}
};
oofsFileSystemDesc *oofsGetFileSystem(oofsFileSystemDesc *nativefs);
Function
Provide the filesystem interface definition.
Parameters
nativefs
the default filesystem class used by the AMS.
Success
A non-null pointer to the oofsFileSystemDesc object is returned.
Failure
A NULL (i.e., 0) pointer is returned.
Notes
Example
class myFileSystem : public oofsFileSystemDesc
{ /* derive appropriate filesystem here */ }
oofsFileSystemDesc *oofsGetFileSystem
(oofsFileSystemDesc *nativefs)
{ return new myFileSystem; }
int exists(const char *path, // In
oofsFileExistance &exists_flag // Out
oofsError &einfo, // Out
oofsCredentials *cred ); // In
Function
Determine whether a path or file exists.
Parameters
path
is the fully qualified name of the file to be tested for existence.
exists_flag
is the address of the variable to hold the status of the test. When a success indication is returned, exists_flag will have one of the following values:
oofsFileExistsNo
The path is neither a file nor a directory.oofsFileExistsIsFile
The specified path refers to an existing fileoofsFileExistsIsDirectory
The specified path refers to an existing directoryeinfo
is the error object informed of any relevant error conditions.
cred
are optional credentials authenticating the remote caller. A null pointer or zero-length credentials indicate that no credentials were supplied.
Success
Zero (0) is returned with exists_flag set.
Failure
OOFS_ERROR
is returned and einfo contains the actual error code and an optional null terminated string describing the nature of the error.
int *getSecurityToken( oofsSecurityToken &token, // Out
struct sockaddr &address, // In
oofsError &einfo); // Out
Function
Return a security token to be used to initialize client-side security.
Parameters
token
is a reference to a buffer to contain the security token that is to be returned to the client to initiate the security protocol. The supplied buffer must be no less than OOFS_MAX_SECURITY_BUFFER_LEN in length.
address
is the network address of the client requesting the information.
einfo
is the error object informed of any relevant error conditions.
Success
Zero (0) is returned with token set
Failure
OOFS_ERROR
is returned and einfo contains the actual error code and an optional null terminated string describing the nature of the error.Notes
oofsDirectory *openDir(const char *dirname, // In
oofsError &einfo, // Out
const oofsCredentials *cred ); // In
Function
Open an oofsDirectory object for reading.
Parameters
dirname
is the name of the directory that is to be opened. Typically, a fully qualified path is given.
einfo
is the error object informed of any relevant error conditions.
cred
are optional credentials authenticating the remote caller. Zero-length credentials indicate that no credentials were supplied.
Success
A non-NULL pointer to an oofsDirectory object is returned.
Failure
A NULL pointer is returned and einfo contains the actual error code and an optional null terminated string describing the nature of the error.
Notes
oofsFile *openFile(const char *filename, // In
oofsFileOpenMode open_mode, // In
oofsFileCreateMode create_mode // In
oofsError &einfo // Out
const oofsCredentials *cred, // In
const oofsOpaqueInfo *info ); // In
Function
Open an oofsFile object file; optionally creating a corresponding disk file.
Parameters
filename
is the name of the file that is to be opened
open_mode
indicates how the file is to be opened or created (i.e., read, write, or update).
create_mode
holds the access mode bits to be assigned to the file when open_mode indicates that the file is to be created.
einfo
is the error object informed of any relevant error conditions.
cred
are optional credentials authenticating the remote caller
info
is an optional pointer to a structure describing opaque information that may be of use during the operation.
Success
A non-NULL pointer to an oofsFile object is returned.
Failure
A NULL pointer is returned and einfo contains the actual error code and an optional null terminated string describing the nature of the error.
Notes
int remove( const char *filename // In
oofsError &einfo, // Out
oofsCredentials *cred ); // In
Function
Remove a file.
Parameters
filename
is the filename of the file to be removed. Normally, a fully qualified path is specified. Asterisks are not allowed in the filename.
cred
are optional credentials authenticating the remote caller. A null pointer or zero-length credentials indicate that no credentials were supplied.
einfo
is the error object informed of any relevant error conditions.
Success
Zero (0) is returned.
Failure
OOFS_ERROR
is returned and einfo contains the actual error code and an optional null terminated string describing the nature of the error.
int rename( const char *old_filename, // In
const char *new_filename, // In
oofsError &einfo, // Out
oofsCredentials *cred ); // In
Function
Rename a file.
Parameters
old_filename
is the existing name of a file. Normally, a fully qualified path is specified.
new_filename
is the name that the file is to have. It must be different from old_filename.
cred
are optional credentials authenticating the remote caller. A null pointer or zero-length credentials indicate that no credentials were supplied.
einfo
is the error object informed of any relevant error conditions.
Success
Zero (0) is returned.
Failure
OOFS_ERROR
is returned and einfo contains the actual error code and an optional null terminated string describing the nature of the error.
int close( oofsCredentials *cred ); // In
Function
Closes an open oofsDirectory object directory.
Parameters
cred
are optional credentials authenticating the remote caller. .A null pointer or zero-length credentials indicate that no credentials were supplied.
Success
Zero (0) is returned.
Failure
OOFS_ERROR
is returned. Use getErrorInfo() to obtain the actual error code and, optionally, a null terminated string describing the nature of the error.
const char * nextEntry( oofsCredentials *cred ); // In
Function
Return the next entry in an open oofsDirectory object directory.
Parameters
cred
are optional credentials authenticating the remote caller. A null pointer or zero-length credentials indicate that no credentials were supplied.
Success
A pointer to a local buffer is returned. The buffer contains the next directory entry’s name.
Failure
Zero (0) is returned. Use getErrorInfo() to obtain the actual error code and, optionally, a null terminated string describing the nature of the error.
Notes
int open(const char *dirname // In
oofsCredentials *cred ); // In
Function
Open a oofsDirectory object directory for reading.
Parameters
dirname
is the name of the directory that is to be opened. Typically, a fully qualified path is given.
cred
are optional credentials authenticating the remote caller. A null pointer or zero-length credentials indicate that no credentials were supplied.
Success
Zero(0) is returned.
Failure
OOFS_ERROR
is returned. Use getErrorInfo() to obtain the actual error code and, optionally, a null terminated string describing the nature of the error.
void getErrorInfo([oofsErrorStruct &einfo]); // Out
Function
Return error information about the last oofs operation..
Parameters
einfo
is an optional pointer to the structure that is to hold the error information.
Success
The error code number is returned if einfo is omitted.
Failure
The function cannot fail.
Notes
void setErrorInfo(const ooUInt32 code, // In
const char *message); // In
Function
Set error information about the last oofs operation..
Parameters
code
is the numeric error code to be recorded.
message
is a pointer to the null-terminated character message to be recorded. The character message must not be longer than
Success
The error code number is returned.
Failure
The function cannot fail.
int close( oofsCredentials *cred ); // In
Function
Close an open oofsFile object’s file.
Parameters
cred
are optional credentials authenticating the remote caller. A null pointer or zero-length credentials indicate that no credentials were supplied.
Success
Zero (0) is returned.
Failure
OOFS_ERROR
is returned. Use getErrorInfo() to obtain the actual error code and, optionally, a null terminated string describing the nature of the error.
int getmode(oofsFileCreateMode &mode, // Out
oofsCredentials *cred ); // In
Function
Return an oofsFile object’s file creation mode.
Parameters
mode
is a pointer to a variable that is to hold the file’s creation mode (i.e., read-write-execute permission bits). The creation mode is returned in POSIX format and only upon success. The returned value may not be meaningful if the file is protected by an access control list.
cred
are optional credentials authenticating the remote caller. A null pointer or zero-length credentials indicate that no credentials were supplied.
Success
Zero (0) is returned with mode set.
Failure
OOFS_ERROR
is returned. Use getErrorInfo() to obtain the actual error code and, optionally, a null terminated string describing the nature of the error.
int getsize(oofsFileOffset &flen, // Out
oofsCredentials *cred ); // In
Function
Return an oofsFile object file’s current size.
Parameters
flen
is a pointer to a variable to hold the file’s current size. The size is returned only upon success.
cred
are optional credentials authenticating the remote caller. A null pointer or zero-length credentials indicate that no credentials were supplied.
Success
Zero (0) is returned with flen set.
Failure
OOFS_ERROR
is returned. Use getErrorInfo() to obtain the actual error code and, optionally, a null terminated string describing the nature of the error.
int open(const char *filename, // In
oofsFileOpenMode open_mode, // In
oofsFileCreateMode create_mode, // In
oofsCredentials *cred, // In
oofsInfoStruct *info ); // In
Function
Open an oofsFile object file; optionally creating a corresponding disk file.
Parameters
filename
is the name of the file that is to be opened. Typically, a fully qualified path is given.
open_mode
indicates how the file is to be opened (i.e., read, write, or update). If open_mode indicates that the file is to be created, the file is also opened in update mode. The following are valid mode values:
OOFS_O_RDONLY
- open file for readingOOFS_O_WRONLY
- open the file for writingOOFS_O_RDWR
- open the file for reading and writing (i.e., update)OOFS_O_CREAT
- create the file and open with OOFS_O_RDWRcreate_mode
holds the access mode bits to be assigned to the file when open_mode indicates that the file is to be created. The mode must be specified in POSIX format (.e.g., 744 corresponds to rwx--r—mode).
cred
are optional credentials authenticating the remote caller. A null pointer or zero-length credentials indicate that no credentials were supplied.
info
is an optional pointer to a structure describing opaque information that may be of use during the operation. Opaque information is only meaningful to oofs routines and is passed with modification from the client. A null pointer or a zero length opaque information indicates that opaque information was not supplied.
Success
Zero (0) is returned.
Failure
OOFS_ERROR
is returned. Use getErrorInfo() to obtain the actual error code and, optionally, a null terminated string describing the nature of the error.Notes
oofsXferSize read(oofsFileOffset offset, // In
char *buffer, // Out
oofs XferSize buffer_size, // In
oofsCredentials *cred ); // In
Function
Read zero or more bytes from an open oofsFile object’s file.
Parameters
offset
is the absolute offset, origin 0, into the file where the read is to begin.
buffer
is a pointer to a buffer that is to hold the contents of the file after the read completes
buffer_size
is the size of the actual buffer. No more than the specified number of bytes are actually read from the file.
cred
are optional credentials authenticating the remote caller. A null pointer or zero-length credentials indicate that no credentials were supplied.
Success
The actual number of bytes that were read.
Failure
OOFS_ERROR
is returned. Use getErrorInfo() to obtain the actual error code and, optionally, a null terminated string describing the nature of the error.
int sync( oofsCredentials *cred ); // In
Function
Verify that all data is committed to permanent media.
Parameters
cred
are optional credentials authenticating the remote caller. A null pointer or zero-length credentials indicate that no credentials were supplied.
Success
Zero (0) is returned.
Failure
OOFS_ERROR
is returned. Use getErrorInfo() to obtain the actual error code and, optionally, a null terminated string describing the nature of the error.
int truncate(oofsFileOffset file_siz, // In
oofsCredentials *cred ); // In
Function
Set the size of a file.
Parameters
file_size
is the new size of the file. If the new size is smaller than the current size, the file is reduced in size and the excess bytes are discarded. If the new size if greater than the current size, the file is extended to the new size with binary zeroes.
cred
are optional credentials authenticating the remote caller. A null pointer or zero-length credentials indicate that no credentials were supplied.
Success
Zero (0) is returned.
Failure
OOFS_ERROR
is returned. Use getErrorInfo() to obtain the actual error code and, optionally, a null terminated string describing the nature of the error.
oofsXferSize write(oofsFileOffset offset, // In
const char *buffer, // In
oofs XferSize buffer_size, // In
oofsCredentials *cred ); // In
Function
Write zero or more bytes into an open oofsFile object’s file.
Parameters
offset
is the absolute offset, origin 0, into the file where the write is to begin.
buffer
is a pointer to a buffer that is to hold the data to be written into the file.
buffer_size
is the size of the actual buffer. No more than the specified number of bytes are actually written to the file.
cred
are optional credentials authenticating the remote caller. A null pointer or zero-length credentials indicate that no credentials were supplied.
Success
The actual number of bytes that were written are returned.
Failure
OOFS_ERROR
is returned. Use getErrorInfo() to obtain the actual error code and, optionally, a null terminated string describing the nature of the error.Notes
G
eneric Authentication Protocol (GAP) allows security information (e.g., credentials) to be transparently transferred from an Objectivity AMS client to the AMS server using a generic mechanism that can be easily modified to use site-specific security. GAP is supported only for AMS mediated connections and is suitable for private-key mechanisms such as Kerberos and Windows NT, and public-key mechanisms such as PGP. It consists of three site-definable client-side functions and a new client-side interface. Generally,The following general steps comprise the GAP (also shown in the diagram):
The appropriate security routines must be packaged in a shared library that the OCSK uses to dynamically load the routines when needed. Therefore, the library must be added to the loader search path used by the OCSK so that it is preferentially used. The routine that creates a new SO’s for each AMS (i.e., there is a 1-to-1 correspondence between an SO’s and AMS’s) must be distinguishable by name. Thus, it needs to be declared as a C routine, as shown in the following example.
class mySecurity : public oofsAMSClientSecurity
{
// Actual security implementation
mySecurity(const struct sock_addr_in &netaddr,
const oofsAMSSecurityIdentifiers &secids)
{
// Perform security initialization
}
}
extern "C" {
oofsAMSClientSecurity *oofs_createSecurityContext
(const struct sock_addr_in &netaddr,
const oofsAMSSecurityIdentifiers &secids)
{
return new mySecurity(netaddr, secids);
}
}
There is one Security Object (SO) for each distinct AMS. An SO is created by oofs_createSecurityContext(). Therefore, for each new AMS that is contacted, the OSCK follows these steps:
oofsFileSystemDesc::oofsgetSecurityToken().
For each request sent to an existing AMS, the OSCK follows these steps using the methods provided by the SO associated with the target AMS:
oofsAMSClientSecurity *oofs_CreateSecurityContext
(const struct sock_addr_in &netaddr, // In
const oofsAMSSecurityIdentifiers &secids); // In
Function
Creates a security object for the specified AMS.
Parameters
netaddr
contains the network address associated with the AMS for which a security object is to be created.
secids
points to the security token returned by the AMS in response to the getSecurityToken() call.
Success
a pointer to the oofsAMSClientSecurity object is returned.
Failure
A null is returned.
Notes
virtual int getCredentials(ooUInt32 operation, // In
const char *pathname, // In
oofsAMSSecurityCredentials &cred); // Out
Function
Obtain credentials for a database operation.
Parameters
operations
indicates the operation that is about to be performed.
pathname
indicates the name of the database against which the operation will be performed.
cred
dis a pointer to the credentials structure where the authentication information is to be placed. The structure is big enough to hold up to. OOFS_MAX_SECURITY_BUFFER_LEN bytes of information.
Success
Zero is returned and the credentials structure is appropriately filled in. The data in the structure, if any, is sent to the AMS along with the request.
Failure
Negative one (-1) is returned. Use getErrorInfo() to obtain the actual error code and, optionally, a null terminated string describing the nature of the error.
Notes
Opaque Information Protocol (OIP) allows arbitrary information (e.g., performance hints) to be transparently transferred from an Objectivity AMS client to the AMS server. OIP is supported only for AMS mediated connections. It consists of one new client-side function, oofs_set_info(). Opaque information is sent to the openFile() function on the AMS side.
Application Steps in OIP
char info[256];
·
·
// Fill in the info array, as needed·
if (oofs_set_info(info, sizeof(info), OOFS_SOI_ONCE)) Fatal_Error();
·
·
// Open objectivity database, sending it the info.·
OCSK Steps in OIP
AMS Steps in OIP
int oofs_set_info(const char *info, // In
const int infolen, // In
oofsSetInfoUset flags);, // In
Function
Set opaque information for subsequent transmission to the AMS.
Parameters
info
points to a buffer containing the information to be sent to the AMS, If the pointer is NULL, current opaque information, if any, is discarded and no information is subsequently sent.
infolen
is the length of the information to be sent to the AMS, If the length is zero, current opaque information, if any, is discarded and no information is subsequently sent.
flags
indicates how the opaque information is to be handled:
oofsSetInfoAlways
- always send the information on subsequent open and create requests.oofsSetInfoOnce
- send the information on the subsequent open or create request and discard the information afterwards (i.e., only send it once).Success
Zero (0) is returned.
Failure
Negative one (-1) is returned.
Notes
Defer Request Protocol (DRP) allows an AMS server to control the timeout of a client’s request. It is included as part of the AMS/OCSK protocol to allow the use of hierarchical filesystems with highly variable latencies (e.g., microseconds to several minutes).
AMS Steps in DRP
|
Function |
Failure Return |
Function |
Failure Return |
|
exists() |
-1 |
remove() |
-1 |
|
OpenDir() |
0 |
rename() |
-1 |
|
openFile() |
0 |
oofsFile::read() |
-1 |
!wait 300
indicates that the client should wait 300 seconds then reissue the same request to the same AMS.
3. The OCSK should treat the retry request as an error if any of the following occurs:
a) The number of seconds is less than 1.
b) The number of seconds is greater than 9999.
c) The number of seconds is not a whole number.
4. Retry errors are to be treated as AMS errors and standard error recovery procedures are to be applied.
Request Redirection Protocol (RRP) allows cooperating AMS’s to perform dynamic load balancing using a simple redirection scheme. A group of cooperating AMS’s, or an AMS Collective (AMSC), is logically treated as a single AMS by the client. There is one distinguished member of the collective and all database catalogue information is tied to the distinguished member (i.e., server). This minimizes the administrative impact on client operations and database descriptions. Therefore, a client need not know the composition of the collective and, indeed, that composition is free to change at any time without impacting any database operations that the client may perform.
The following figure illustrates an AMS collective and a simple redirection interaction.
Redirection allows an AMS to direct a client to a more suitable AMS for processing the client’s request. Because the server redirects the request, it is possible to implement a highly flexible and scalable dynamic load-balancing scheme than would otherwise be possible by other mechanisms. For instance, the database load may be balanced using one or more of the following criteria, among others:
RRP also allows the AMS to dynamically replicate databases on demand. For instance, should a databases become highly used, the AMS could replicate the database at one or more other sites and redirect clients to other copies. Once the database becomes less heavily used, the extra copies can be eliminated to save space.
Dynamic load balancing does not alter any current multi-AMS protocols such as the Data Replication Option (DRO) or the Fault Tolerant Option (FTO). This is because the collective is defined outside the scope of such protocols. Furthermore, each AMSC member is effectively interchangeable in the context of the collective. Nevertheless, it is possible to implement collectives in ways that render DRO and FTO unusable.
The collective is responsible for providing update synchronization should any AMSC members allow write operations. Should a client wish to update a database and a modifiable database replica exists outside of the collective, it is the application’s responsibility to explicitly indicate that write operations will occur before performing any transactions against the database.
Redirection of requests is only supported for operations against a closed database (i.e., operations that use a filename instead of a filehandle). This includes the openFile() and openDir() requests.
|
Function |
Failure Return |
Function |
Failure Return |
|
exists() |
-1 |
remove() |
-1 |
|
OpenDir() |
0 |
rename() |
-1 |
|
openFile() |
0 |
!try abh.slac.stanford.edu
indicates that the client should reissue the same request to the AMS located on host "abh.slac.stanford.edu".
2. Should a redirect request be received, the OCSK must send the same request to the specified AMS.
3. The OCSK should treat the redirect request as an error if any of the following occurs:
a) The redirect specifies the same AMS.
b) More than 255 consecutive redirect requests have been received.
c) The specified AMS does not exist or refuses a connection.
4. Redirection errors are to be treated as AMS errors and standard error recovery procedures are to be applied.
Appendix A
Real Time Monitor Record Format
rectype.version date time host srv &varname=val[&varname=val[. . .]]eor
Parameters
rectype
is the two character record type identifier followed by a period. Refer to the following section on information about record types.
version
is the version number of the record as a decimal number followed by a space.
date
the date the record was generated in yyyymmdd format; where yyyy is the four digit year, mm is the two digit month, and dd is the two digit day of the month. The date is followed by a space.
time
the time the record was generated in hhmmss.uuuu format, where hh is the hour in 24-hour time, mm is the minute, and ss is the second, uuuu is the microsecond. The time is followed by a space.
host
is the name of the host that generated the record. The hostname is followed by a space.
srv
is the logical name of the service producing the record. Valid service names are:
ams Advanced Multi-threaded Server
mig Migration Service
prg Purge Service
stg Staging Service
varname
is a variable name associated with a recorded statistical value. The variable name is typically preceded by an ampersand (the actual character is selectable) and followed by an equal sign. Refer to the following section on information about variable names.
val
is the value associated with the variable. Refer to the following section on information about possible values.
eor
is an end-of-record character, typically a new line (\n). The character is selectable. Refer to the following section on information about record types.
The following table lists all possible record types. Currently, the version number associated with each record type is one (1).
|
Type |
Contents |
|
br |
A monitoring break has occurred due to a restart or reset. |
|
cd |
A directory has been closed; record contains final statistics. |
|
cf |
A file has been closed; record contains final statistics. |
|
ds |
Directory summary statistics on directory i/o activities. |
|
fs |
File summary statistics on file i/o activities. |
|
io |
Current statistics on an open file. |
|
of |
A file has been opened (does not include directories). |
|
sk |
Seek monitor record |
|
ss |
Summary statistics on meta-data operations. |
For monitoring break records (i.e., br), only header data is present. Additionally, all counters are reset to their initial values. Therefore, subsequent values may appear to be smaller than preceeding values.
Values in repetitive records are cumulative. That is, the values in record (n) also include the values in record (n-1). This allows a data collector to miss monitoring records without loss of data with the monitoring window automatically increasing in proportion to the number of records missed. Repetitive records are:
ds fs ss
Values in event records are singleton. That is, the represent the value in effect at the time the data was collected. For instance, cf records will contain all of the data relevant to the file being closed. A subsequent cf record for the same file will represent another unique use of the file and the data in the subsequent record will not be related to any previous cf record for the same file. Event records are:
br cd cf of sk
Values in session records are cumulative for the duration of the session. For instance, io records represent a session between an of and cf event for a particular file. Therefore, all io records between the corresponding of and cf records are cumulative. Session records are:
io
|
Var |
Type |
Contents |
|
ncls |
int |
Number of close() or closedir() calls. |
|
nexi |
int |
Number of exists() calls. |
|
ngmd |
int |
Number of getmode() calls. |
|
ngsz |
int |
Number of getsize() calls. |
|
nopn |
int |
Number of open() or opendir() calls. |
|
nrd |
int |
Number of getnext() or read() calls. |
|
nrem |
int |
Number of remove() calls. |
|
nren |
int |
Number of rename() calls. |
|
nstg |
int |
Number of open() calls that required a stage operation. |
|
nsyn |
int |
Number of sync() calls. |
|
ntru |
int |
Number of truncate() calls. |
|
nusr |
int |
of : Number of current users. cf: Maximum number of users. |
|
nwr |
int |
Number of write() calls. |
|
offs |
int |
Byte offset into file of a read (with qxfr)or write (with qxfw). |
|
path |
char |
Path name if record is for a specific file or directory. |
|
ptid |
int |
Path ID associated with the indicated path. |
|
qxfr |
float |
Number of bytes transferred for read operations. |
|
qxfw |
float |
Number of bytes transferred for write operations. |
|
scpu |
float |
Number of seconds accumulated in system space. |
|
skew |
float |
Seek skew statistic: sequential access as value approaches zero. |
|
topn |
float |
Elapsed seconds spent opening object (i.e. file or directory). |
|
tsyn |
float |
Elapsed seconds spent in the system fsync() routine. |
|
tuse |
float |
Elapsed seconds file or directory was open, less open time. |
|
txfr |
float |
Elapsed seconds spent reading data. |
|
txfw |
float |
Elapsed seconds spent writing data. |
|
ucpu |
float |
Number of seconds accumulated in user space. |
|
user |
char |
The identifiable user, if any, responsible for this record. |
|
Var |
cd |
cf |
ds |
fs |
io |
of |
sk |
ss |
|
ncls |
ü |
ü |
||||||
|
nexi |
ü |
|||||||
|
ngmd |
ü |
|||||||
|
ngsz |
ü |
|||||||
|
nopn |
ü |
ü |
||||||
|
nrd |
ü |
ü |
ü |
ü |
ü |
|||
|
nrem |
ü |
|||||||
|
nren |
ü |
|||||||
|
nstg |
ü |
|||||||
|
nsyn |
ü |
ü |
||||||
|
ntru |
ü |
|||||||
|
nusr |
ü |
ü |
||||||
|
nwr |
ü |
ü |
ü |
|||||
|
offs |
ü |
|||||||
|
path |
ü |
ü |
ü |
|||||
|
ptid |
ü |
ü |
ü |
ü |
ü |
|||
|
qxfr |
ü |
ü |
ü |
ü |
ü |
ü |
||
|
qxfw |
ü |
ü |
ü |
ü |
||||
|
scpu |
ü |
|||||||
|
skew |
ü |
ü |
||||||
|
topn |
ü |
ü |
||||||
|
tsyn |
ü |
ü |
ü |
|||||
|
tuse |
ü |
ü |
ü |
|||||
|
txfr |
ü |
ü |
ü |
ü |
ü |
|||
|
txfw |
ü |
ü |
ü |
|||||
|
ucpu |
ü |
|||||||
|
user |
ü |
ü |
ü |
ü |