0539 nwnss: import NSS error status runtime

This commit is contained in:
ChatGPT
2026-06-14 22:29:10 +00:00
committed by Mario Fetka
parent ce4d6c9e10
commit b3f73a64b8
9 changed files with 1027 additions and 0 deletions

315
include/nwnss/include/msg.h Normal file
View File

@@ -0,0 +1,315 @@
/****************************************************************************
|
| (C) Copyright 1995-1998 Novell, Inc.
| All Rights Reserved.
|
| This program is free software; you can redistribute it and/or
| modify it under the terms of version 2 of the GNU General Public
| License as published by the Free Software Foundation.
|
| This program is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
| GNU General Public License for more details.
|
| You should have received a copy of the GNU General Public License
| along with this program; if not, contact Novell, Inc.
|
| To contact Novell about this file by physical or electronic mail,
| you may find current contact information at www.novell.com
|
|***************************************************************************
|
| NetWare Storage Services (NSS) module
|
|---------------------------------------------------------------------------
|
| $Author: taysom $
| $Date: 2007-04-12 01:48:56 +0530 (Thu, 12 Apr 2007) $
|
| $RCSfile$
| $Revision: 1932 $
|
|---------------------------------------------------------------------------
| This module is used to:
| Define the message structures used by NSS and the bit masks and
| other values used by NSS APIs.
+-------------------------------------------------------------------------*/
#ifndef _NSS_MSG_H_
#define _NSS_MSG_H_
#ifndef _ZOMNI_H_
# include <zOmni.h>
#endif
#ifndef _ZMSG_H_
# include <zMsg.h>
#endif
#ifndef _QUE_H_
# include <que.h>
#endif
#ifndef _SLAB_H
# include <slab.h>
#endif
typedef void *(*objfunc_t)(); /* Function returns a pointer to an object */
typedef struct XIPC_Msg_s
{
zWorkProc_s work;
CIRlink_t link;
void *page;
struct net_s
{
LONG dataLength;
LONG type;
QUAD key;
LONG method;
Msg_s msg;
} net;
} XIPC_Msg_s;
/*
* An Object is an instance of a Type. The Object holds the data
* while the Type has the methods.
*/
typedef struct mObject_s
{
struct mType_s *o_type; /* Type of the object -- methods */
NINT o_count; /* Number of references to object */
DQlink_t o_instance; /* Other instances of this object type */
NINT o_properties;
#if 0
// struct {
// NINT w_next;
//#define NUM_WHERE 32
// char *w_where[NUM_WHERE];
// } o_w;
#endif
} mObject_s;
#if 0
#define OBJ_TRACE(_obj) \
((_obj)->o_w.w_where[(_obj)->o_w.w_next++ & (NUM_WHERE-1)] = WHERE)
#endif
/*
* A door maps a key to an object and keeps track of
* who owns the object.
*/
typedef struct mDoor_s
{
mObject_s dr_obj;
struct mDoor_s *dr_next;
Key_t dr_key;
struct mManager_s *dr_owner;
DQlink_t dr_ownerList;
} mDoor_s;
/*
* Managers create and own doors. It has a table of doors
* that it manages. In a more traditional system, this would
* be a process.
*/
typedef struct mManager_s
{
mObject_s obj;
DQhead_t doors; /* All the doors this manager owns */
DQhead_t types; /* All the types this manager created */
} mManager_s;
/*
* Each Door Manager can manage a number of different
* door types. This could also be thought of as a class.
* All the methods are held by the type.
*
* In addition to the method table, a number of standard
* functions can be set. If not supplied, a default function
* will be provided.
* preconstructor - used by objCache to initialize obj when
* slab is first allocated. Not called
* on subsequent allocations.
* constructor - called each time the object is allocated to
* initialize the object. Because no
* arguments can be passed, this is of
* limited use.
* destructor - called to clean up the object.
* notify - called to notify someone that the object
* is about to be destroyed.
* unregister - called when unregistering a type. Example:
* types that have doors, will use MSG_BreakDoor.
*/
#define MSG_INIT_TYPE(name, parent, objSize, numMethods, \
preconstructor, constructor, destructor, notify, unregister)\
{ \
name, parent, objSize, numMethods, NULL, \
(voidfunc_t)preconstructor, (objfunc_t)constructor, \
(statusfunc_t)destructor, (voidfunc_t)notify, \
(voidfunc_t)unregister, \
{ 0 } \
}
typedef struct mTypeHeader_s
{
char *name;
struct mTypeHeader_s *parent; /* Weak inheritance */
NINT objSize;
NINT numMethods;
mManager_s *manager;
voidfunc_t preconstructor;
objfunc_t constructor;
statusfunc_t destructor; // Used in multiple places
voidfunc_t notify;
voidfunc_t unregister;
DQlink_t typeList;
DQhead_t instances;
ObjCache_s objCache;
} mTypeHeader_s;
typedef struct mType_s
{
mTypeHeader_s hdr;
statusfunc_t method[1];
} mType_s;
/*
* The Manager Manager.
*/
#define NUM_MGR_METHODS 0
typedef struct mVirtualType_s /* Has no methods nor objects */
{
mTypeHeader_s hdr;
} mVirtualType_s;
typedef STATUS (*MSG_RemoteMethod_t)(
mDoor_s *door,
NINT method,
Msg_s *msg);
typedef STATUS (*MSG_RemoteMethodKey_t)(
mDoor_s *door,
NINT method,
Msg_s *msg,
mDoor_s *passedDoor);
extern mVirtualType_s DoorType;
extern mVirtualType_s ManagerType;
extern mManager_s *Manager;
/**********************
* Function prototypes
*/
STATUS MSG_DestroyKey(Key_t key);
STATUS NullMethod(Msg_s *msg);
STATUS MSG_Call(
Key_t key,
NINT method,
Msg_s *msg);
STATUS MSG_SendKey(
Key_t key,
NINT method,
Msg_s *msg);
STATUS zMSG_Call(
Key_t key,
NINT method,
Msg_s *msg);
STATUS mpkMSG_Call(
Key_t key,
NINT method,
Msg_s *msg);
STATUS MSG_Send(
Key_t key,
NINT method,
Msg_s *msg);
void MSG_ChangeOwner(
mDoor_s *door,
mManager_s *owner);
void *MSG_CreateDoor(
mTypeHeader_s *type,
mManager_s *manager,
NINT properties,
Key_t *retKey);
void *MSG_CreateObject(
mTypeHeader_s *type);
void MSG_ReleaseObject(mObject_s *obj);
STATUS MSG_DestroyKey(Key_t key);
STATUS MSG_RegisterType(
mTypeHeader_s *type,
mManager_s *manager);
void MSG_UnregisterType(mTypeHeader_s *type);
void MSG_KillManager(mManager_s *mgr);
STATUS MSG_BreakDoor(mDoor_s *door);
void MSG_BreakSetOfDoors(
mTypeHeader_s *type,
boolfunc_t match,
void *args);
void MSG_DestroySetOfKeys(
mManager_s *owner,
mTypeHeader_s *type,
boolfunc_t match,
void *args);
Key_t MSG_LookupShortKey(LONG key);
void msgFreeDoor(mDoor_s *door);
extern NINT NSS_StoreCallers(void **, NINT,SNINT);
#define MSG_USE_OBJECT(_obj) (++(_obj).o_count)
#define MSG_RELEASE_OBJECT(_obj) { \
(--(_obj).o_count); \
MSG_ReleaseObject( &(_obj)); \
}
#define MSG_USE_DOOR(_door) (++(_door)->dr_obj.o_count)
/*
* The door should be freed.
* By giving a door an initial count of zero, we
* can handle one time doors here without any
* additional tests.
* Re-get the type because the door may have
* been broken while the last message was being
* processed.
*/
#define MSG_RELEASE_DOOR(_door) \
{ \
--(_door)->dr_obj.o_count; \
if ((_door)->dr_obj.o_count == 0) \
{ \
msgFreeDoor(_door); \
} \
}
void MSG_RegisterXIPC(
MSG_RemoteMethod_t call,
MSG_RemoteMethod_t send,
MSG_RemoteMethodKey_t sendKey);
void MSG_UnregisterXIPC(void);
extern mDoor_s *findDoor(Key_t key);
extern XIPC_Msg_s *allocMsgBuf();
extern void freeMsgBuf(XIPC_Msg_s *xmsg);
#endif

View File

@@ -0,0 +1,288 @@
/****************************************************************************
|
| (C) Copyright 1985, 1991, 1993, 1996 Novell, Inc.
| All Rights Reserved.
|
| This program is free software; you can redistribute it and/or
| modify it under the terms of version 2 of the GNU General Public
| License as published by the Free Software Foundation.
|
| This program is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
| GNU General Public License for more details.
|
| You should have received a copy of the GNU General Public License
| along with this program; if not, contact Novell, Inc.
|
| To contact Novell about this file by physical or electronic mail,
| you may find current contact information at www.novell.com
|
|***************************************************************************
|
| NetWare Advance File Services (NSS) General Message Structure defines
|
|---------------------------------------------------------------------------
|
| $Author: randys $
| $Date: 2005-06-06 19:11:43 +0530 (Mon, 06 Jun 2005) $
|
| $RCSfile$
| $Revision: 1029 $
|
|---------------------------------------------------------------------------
| This module is used to:
| Define the MESSAGE structure that is passed between layers of the
| system.
|
| WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING! WARNING!
|
| This header file should ONLY be used for NSS internal development.
| This includes Semantic Agents (SA) and Loadable Storage Services (LSS).
| Any other use may cause conflicts which NSS will NOT fix.
+-------------------------------------------------------------------------*/
#ifndef _MSGGEN_H_
#define _MSGGEN_H_
#ifndef _ZOMNI_H_
# include <zOmni.h>
#endif
#ifndef _XSTRING_H_
# include <xString.h>
#endif
#ifndef _LATCH_H_
# include <latch.h>
#endif
#ifndef _XERROR_H_
# include <xError.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*---------------------------------------------------------------------------
* Pattern used to FILL the MSG structures with while DEBUG is enabled
*---------------------------------------------------------------------------*/
#define COMN_MSG_FILL_PATTERN 0xA5A5A5A5
#if NSS_DEBUG IS_ENABLED
# define COMN_MSG_FILL(_buf,_size) \
(zASSERT(((_size) & (sizeof(LONG)-1)) == 0), \
LB_memlset((_buf),COMN_MSG_FILL_PATTERN,((_size)/sizeof(LONG))))
#else
# define COMN_MSG_FILL(_buf,_size) ((void) 0)
#endif
/*---------------------------------------------------------------------------
* This MACRO is used to INITIALIZE any structure with a pattern. This
* MUST be used before a MSG or PARAM struct is initialized with data.
*---------------------------------------------------------------------------*/
#define COMN_STRUCT_INIT(_msg) \
COMN_MSG_FILL(&(_msg),sizeof(_msg))
//#if NSS_DEBUG IS_ENABLED
//# define COMN_CHECK_STRUCT_INIT(_genMsg) zASSERT((_genMsg)->fillCheck == COMN_MSG_FILL_PATTERN)
//#else
//# define COMN_CHECK_STRUCT_INIT(_genMsg) ((void) 0)
//#endif
/*===========================================================================
*===========================================================================
*===========================================================================
*
* This defines basic structures used to keep track of HANDLE ID's and
* their associated pointers. With these ID/POINTER pairs we can cache
* the pointers in memory so we don't have to keep resolveing the ID's
*
*===========================================================================
*===========================================================================
*===========================================================================*/
/*---------------------------------------------------------------------------
* IDP for conections
*---------------------------------------------------------------------------*/
typedef struct ConnectionIDP_s
{
NINT id; /* connectionID */
struct NSSConnection_s *ptr;
} ConnectionIDP_s;
#define COMN_SET_CONNECTION_ID(_conIDP,_conid) \
(((_conIDP)->id = (_conid)),((_conIDP)->ptr = NULL))
/*---------------------------------------------------------------------------
* IDP for context handles
*---------------------------------------------------------------------------*/
typedef struct ContextHandleIDP_s
{
NINT id; /* contextHandleID */
struct ContextHandleInfo_s *ptr;
} ContextHandleIDP_s;
#define COMN_SET_CONTEXTHANDLE(_cxIDP,_cxid,_cxptr) \
(((_cxIDP)->id = (_cxid)),((_cxIDP)->ptr = (_cxptr)))
#define COMN_SET_CONTEXTHANDLE_ID(_cxIDP,_cxid) \
COMN_SET_CONTEXTHANDLE(_cxIDP,_cxid,NULL)
/*---------------------------------------------------------------------------
* IDP for file handles
*---------------------------------------------------------------------------*/
typedef struct FileHandleIDP_s
{
Key_t key;
struct FileHandle_s *ptr;
} FileHandleIDP_s;
#define COMN_SET_FILEHANDLE(_fhIDP,_fhkey,_fhptr) \
(((_fhIDP)->key = (_fhkey)),((_fhIDP)->ptr = (_fhptr)))
#define COMN_SET_FILEHANDLE_ID(_fhIDP,_fhkey) \
COMN_SET_FILEHANDLE(_fhIDP,_fhkey,NULL)
/*---------------------------------------------------------------------------
* IDP for generic semantic agent handles
*---------------------------------------------------------------------------*/
typedef struct SAHandleIDP_s
{
NINT id; /* semantic Agent HandleID*/
struct SAHandle_s *ptr;
} SAHandleIDP_s;
#define COMN_SET_SAHANDLE(_sahIDP,_sahid,_sahptr) \
(((_sahIDP)->id = (_sahid)),((_sahIDP)->ptr = (_sahptr)))
#define COMN_SET_SAHANDLE_ID(_sahIDP,_sahid) \
COMN_SET_SAHANDLE(_sahIDP,_sahid,NULL)
/*---------------------------------------------------------------------------
* IDP for search maps
*---------------------------------------------------------------------------*/
typedef struct SearchMapIDP_s
{
NINT id; /* searchMapID */
struct SearchMap_s *ptr;
} SearchMapIDP_s;
#define COMN_SET_SEARCHMAP(_smIDP,_smid,_smptr) \
(((_smIDP)->id = (_smid)),((_smIDP)->ptr = (_smptr)))
#define COMN_SET_SEARCHMAP_ID(_smIDP,_smid) \
COMN_SET_SEARCHMAP(_smIDP,_smid,NULL)
/*---------------------------------------------------------------------------
* This contains GENERAL parameters across ALL APIs
*---------------------------------------------------------------------------*/
typedef struct GeneralMsg_s
{
STATUS errStatus; /* holds current status*/
char *errStatusSetter; /* WHERE information. Used
* to determine who set errStatus last.
* This should be only used for
* debug purposes.
*/
ConnectionIDP_s pssConn; /* connection ID*/
NINT taskID; /* taskID for this operation*/
WORD saID; /* semantic agent making the call */
WORD flags; /* to see if the openFiles have a
* latch already on the conn */
} GeneralMsg_s;
/* Values for flags */
#define FILEHANDLE_IS_XLATCHED 0x0001
#define DO_NOT_SEND_EVENTS 0x0002
#define DO_NOT_SEND_FSHOOKS 0x0004
#define ALLOW_SECURE_ACCESS 0x0008
#define DO_NOT_UNPACK_FMAP 0x0010
#define COPY_FMAP_TO_SNAP 0x0020
#define GM_FLAGS_INTERNAL_VOLUME 0x0040 /* Set if user is using an internal
* volume. The caller must set
* this bit for lookup of the volume
* to succeed. ZLSS uses internal
* volumes to store information
* about Logical Volumes in a Pool.
*/
#define ALLOW_INACTIVE_VOLUME 0x0080 /* Set by purgeLog processing to
* cause volume lookups to not
* require the volume to be active
*/
#define UPDATE_EXISTING_BEAST 0x0200 /* When unpacking the beast, it is
* not a new beast, but an existing
* beast that needs to be updated
* used by XLSS.
*/
#define DO_NOT_CHECK_SPACE_QUOTA 0x0400 /* If set, do not check for user space
* restriction and directory space
* restriction
*/
#define ALLOW_BST_STATE_PURGING 0x0800 /* WARNING --- DO NOT USE THIS
* UNLESS YOU KNOW EXACTLY WHAT
* YOU ARE DOING!!!!
* If set, this allows a beast
* to be looked up even if it's
* state is BST_STATE_PURGING, but
* only if it has a non-zero use
* count.
*/
#define COMN_GENMSG_RESOLVE_CONNECTION(genMsg) \
(((genMsg)->pssConn.ptr != NULL) ? (genMsg)->pssConn.ptr : COMN_DoResolveConnection((genMsg)))
/* Note - must set saID and flags before calling COMN_GENMSG_RESOLVE_CONNECTION
* in this macro. COMN_DoResolveConnection sets some flags based on
* the saID field.
*/
#define COMN_SETUP_GENERAL_MSG(_genMsg,_conid,_ptaskid,_sagentID) \
(ClearErrno((_genMsg)), \
(_genMsg)->saID = (_sagentID), \
(_genMsg)->flags = 0), \
(_genMsg)->taskID = (_ptaskid), \
COMN_SET_CONNECTION_ID(&(_genMsg)->pssConn,_conid), \
COMN_GENMSG_RESOLVE_CONNECTION(_genMsg)
#define COMN_SETUP_GENERAL_MSG_NOSA(_genMsg) \
COMN_SETUP_GENERAL_MSG(_genMsg,zSYS_CONNECTION, \
zNO_TASK,zSAGENT_NONE)
#define COMN_SETUP_GENERAL_MSG_NO_CONNECTION_RESOLVE(_genMsg) \
(ClearErrno((_genMsg)), \
COMN_SET_CONNECTION_ID(&(_genMsg)->pssConn,zSYS_CONNECTION), \
(_genMsg)->taskID = (zNO_TASK), \
(_genMsg)->saID = (zSAGENT_NONE), \
(_genMsg)->flags = 0)
#define X_LATCH_SET_FLAG(genMsg, latch) \
{ \
X_LATCH(latch); \
(genMsg)->flags |= FILEHANDLE_IS_XLATCHED; \
}
#define UNX_LATCH_SET_FLAG(genMsg, latch) \
{ \
UNX_LATCH(latch); \
(genMsg)->flags &= ~FILEHANDLE_IS_XLATCHED; \
}
#ifdef __cplusplus
}
#endif
#endif /* _MSGGEN_H_ */

182
include/nwnss/public/zMsg.h Normal file
View File

@@ -0,0 +1,182 @@
/****************************************************************************
|
| (C) Copyright 2001 Novell, Inc.
| All Rights Reserved.
|
| This program is free software; you can redistribute it and/or
| modify it under the terms of version 2 of the GNU General Public
| License as published by the Free Software Foundation.
|
| This program is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
| GNU General Public License for more details.
|
| You should have received a copy of the GNU General Public License
| along with this program; if not, contact Novell, Inc.
|
| To contact Novell about this file by physical or electronic mail,
| you may find current contact information at www.novell.com
|
|***************************************************************************
|
| NetWare Storage Services (NSS) module
|
|---------------------------------------------------------------------------
|
| $Author: taysom $
| $Date: 2006-12-13 05:04:43 +0530 (Wed, 13 Dec 2006) $
|
| $RCSfile$
| $Revision: 1760 $
|
|---------------------------------------------------------------------------
| This module is used to:
| Define the message structures used by NSS and the bit masks and
| other values used by NSS APIs.
+-------------------------------------------------------------------------*/
#ifndef _ZMSG_H_
#define _ZMSG_H_
#ifndef _ZOMNI_H_
# include <zOmni.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*
* Key properties. 'm' added because of conflicts with NWREG.H.
*/
#define mKEY_NOTIFY 0x1
#define mKEY_DUPLICATE 0x2
#define mKEY_1_USE 0x4
#define mKEY_PASS_1_USE 0x8
#define mKEY_PASS_N_USE 0x10
#define mKEY_PASS_ANY (mKEY_PASS_1_USE | mKEY_PASS_N_USE)
#define mKEY_REMOTE 0x20
#define mKEY_DYING 0x40
#define mKEY_DESTRUCT 0x80
/* Valid properties when creating a door */
#define mKEY_VALID_PROPERTIES (mKEY_NOTIFY | mKEY_DUPLICATE | mKEY_1_USE \
| mKEY_PASS_ANY)
#define INVALID_KEY 0
/********************
* Message Structure
* The following definitions of SystemMsg structure have been designed to
* allow application compiled on a 32 bit little-endian machine work on
* a 64 bit little-endian machine.
*/
#define MAX_DATA_AREAS 2
#ifdef __LP64__
#define zPADDING(_x)
#else
#define zPADDING(_x) LONG padding ## _x ;
#endif
struct kernelDataArea_s
{
void *start;
zPADDING(start);
NINT length;
zPADDING(length);
};
struct kernelSystemMsg_s
{
STATUS status; /* Status of the operation */
/* Placed first to match genMsg */
BYTE numDataAreas;/* Number of data areas */
BYTE readMask; /* Data areas that are readable */
BYTE writeMask; /* Data areas that are writeable */
BYTE padding[1];
char *where; /* Where in the code the status was set */
zPADDING(where)
Key_t passedKey; /* Key that was passed with the request */
struct mDoor_s *door; /* Door/obj msg was send through */
zPADDING(door)
struct mManager_s *owner; /* Owner of the object */
zPADDING(owner)
struct kernelDataArea_s data[MAX_DATA_AREAS];
voidfunc_t callback; /* Call back function */
zPADDING(callback)
};
struct userDataArea_s
{
QUAD start;
QUAD length;
};
struct userSystemMsg_s
{
STATUS status; /* Status of the operation */
/* Placed first to match genMsg */
BYTE numDataAreas;/* Number of data areas */
BYTE readMask; /* Data areas that are readable */
BYTE writeMask; /* Data areas that are writeable */
BYTE padding[1];
QUAD where; /* Where in the code the status was set */
Key_t passedKey; /* Key that was passed with the request */
QUAD door; /* Door/obj msg was send through */
QUAD owner; /* Owner of the object */
struct userDataArea_s data[MAX_DATA_AREAS];
QUAD callback; /* Call back function */
};
#ifdef __KERNEL__
typedef struct kernelDataArea_s mDataArea_s;
typedef struct kernelSystemMsg_s mSystemMsg_s;
#else
typedef struct userDataArea_s mDataArea_s;
typedef struct userSystemMsg_s mSystemMsg_s;
#endif
enum { DATA_AREA_CORRECT =
1 / (sizeof(struct kernelDataArea_s) == sizeof(struct userDataArea_s)),
SYSTEM_MSG_CORRECT =
1 / (sizeof(struct kernelSystemMsg_s) == sizeof(struct userSystemMsg_s))
};
/* This number should be small but engineered to the
* system, so the message can be passed in registers
* on a machine with a reasonable number of registers.
* (Remember, the header will have to passed in the
* registers too).
*/
#define MSG_BODY_SIZE 128
typedef union mBody_u
{
QUAD quad[MSG_BODY_SIZE/sizeof(QUAD)];
LONG ulng[MSG_BODY_SIZE/sizeof(LONG)];
WORD word[MSG_BODY_SIZE/sizeof(WORD)];
BYTE byte[MSG_BODY_SIZE/sizeof(BYTE)];
} mBody_u;
typedef struct Msg_s
{
mSystemMsg_s sys;
mBody_u body;
} Msg_s;
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -102,6 +102,7 @@ add_library(nwnss SHARED
nss/lib/bitmap.c
nss/lib/crc.c
nss/lib/hash.c
nss/lib/setErrno.c
nss/msg/slab.c
unicodeTableBuild.c
utcUserland.c)

View File

@@ -0,0 +1,167 @@
/****************************************************************************
|
| (C) Copyright 1985, 1991, 1993, 1996 Novell, Inc.
| All Rights Reserved.
|
| This program is free software; you can redistribute it and/or
| modify it under the terms of version 2 of the GNU General Public
| License as published by the Free Software Foundation.
|
| This program is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
| GNU General Public License for more details.
|
| You should have received a copy of the GNU General Public License
| along with this program; if not, contact Novell, Inc.
|
| To contact Novell about this file by physical or electronic mail,
| you may find current contact information at www.novell.com
|
|***************************************************************************
|
| NetWare Advance File Services (NSS) Initialization module
|
|---------------------------------------------------------------------------
|
| $Author: gpachner $
| $Date: 2006-09-14 03:22:08 +0530 (Thu, 14 Sep 2006) $
|
| $RCSfile$
| $Revision: 1529 $
|
|---------------------------------------------------------------------------
| This module is used to:
| General PSS Error handling routines
+-------------------------------------------------------------------------*/
#include <xError.h>
#include <stdint.h>
#include <msgGen.h>
#include <msg.h>
#include <utc.h>
/* Linux userspace port: NSS kernel RunningProcess is represented by 0 here. */
#ifndef RunningProcess
#define RunningProcess ((ADDR)0)
#endif
#if NSS_DEBUG IS_ENABLED
#define ERROR_LOG_SIZE 4000
#else
#define ERROR_LOG_SIZE 2000
#endif
typedef struct ErrorLog_s
{
STATUS errCode;
char *where;
LONG utcTime;
ADDR thread;
} ErrorLog_s;
typedef struct NSSErrorLog_s
{
QUAD NEL_ErrorCount;
NINT NEL_ErrorLogSize;
ErrorLog_s *NEL_NextError;
ErrorLog_s NEL_ErrorLog[ERROR_LOG_SIZE];
} NSSErrorLog_s;
NSSErrorLog_s NSS_ErrorItems =
{
0, ERROR_LOG_SIZE, &NSS_ErrorItems.NEL_ErrorLog[0]
};
#define LOG_ERROR(_status, _where) \
{ \
NSS_ErrorItems.NEL_NextError->errCode = _status; \
NSS_ErrorItems.NEL_NextError->where = _where; \
NSS_ErrorItems.NEL_NextError->utcTime = GetUTCTime(); \
NSS_ErrorItems.NEL_NextError->thread = RunningProcess; \
NSS_ErrorItems.NEL_ErrorCount += 1; \
if (++NSS_ErrorItems.NEL_NextError == &NSS_ErrorItems.NEL_ErrorLog[ERROR_LOG_SIZE]) \
{ \
NSS_ErrorItems.NEL_NextError = &NSS_ErrorItems.NEL_ErrorLog[0]; \
} \
}
void LB_ForceSetErrnoWithWhere( GeneralMsg_s *genMsg, STATUS status, char *where )
{
genMsg->errStatus = status;
genMsg->errStatusSetter = where;
LOG_ERROR(status, where);
return;
}
/**************************************************************************
* This will set an ERROR into the ERRNO field of the msg structure.
* Following are the rules for setting errors:
* - OUT OF SPACE errors are always set.
* - OUT OF MEMORY errors are set if current error is not OUT_OF_SPACE.
* - We will only set an error if there is not currently an error.
***************************************************************************/
void LB_SetErrno(
GeneralMsg_s *genMsg,
STATUS status,
char *where
)
{
zASSERT(genMsg != NULL);
if (genMsg != NULL)
{
/*COMN_CHECK_STRUCT_INIT(genMsg);*/
if (genMsg->errStatus == zOK)
{
genMsg->errStatus = status;
genMsg->errStatusSetter = where;
}
else
{
if ((genMsg->errStatus != zERR_OUT_OF_SPACE) &&
((status == zERR_NO_MEMORY) ||
(status == zERR_OUT_OF_SPACE)))
{
genMsg->errStatus = status;
genMsg->errStatusSetter = where;
}
}
}
LOG_ERROR(status, where);
}
/*
* SetStatus replaces SetErrno as we convert over to message layer
*/
void MSG_SetStatus (
void *voidMsg,
STATUS status,
char *where)
{
Msg_s *msg = voidMsg;
zASSERT(msg != NULL);
if (msg->sys.status == zOK)
{
msg->sys.status = status;
msg->sys.where = (QUAD)(uintptr_t)where;
}
else
{
if ((msg->sys.status != zERR_OUT_OF_SPACE) &&
((status == zERR_NO_MEMORY) ||
(status == zERR_OUT_OF_SPACE)))
{
msg->sys.status = status;
msg->sys.where = (QUAD)(uintptr_t)where;
}
}
LOG_ERROR(status, where);
}

View File

@@ -40,6 +40,7 @@ if(MARS_NWE_BUILD_NWFS_TESTS)
add_subdirectory(nwnss/parse)
add_subdirectory(nwnss/fsm)
add_subdirectory(nwnss/latch)
add_subdirectory(nwnss/xerror)
add_subdirectory(nwnss/zalloc)
add_subdirectory(nwnss/stdio)
add_subdirectory(nwnss/wio)

View File

@@ -35,3 +35,5 @@ add_subdirectory(worktodo)
add_subdirectory(xctype)
add_subdirectory(xstring)
add_subdirectory(zalloc)
add_subdirectory(xerror)

View File

@@ -0,0 +1,3 @@
add_executable(test_nwnss_xerror test_nwnss_xerror.c)
target_link_libraries(test_nwnss_xerror PRIVATE mars_nwe::nwnss)
add_test(NAME nwnss.xerror COMMAND test_nwnss_xerror)

View File

@@ -0,0 +1,68 @@
#include <msgGen.h>
#include <msg.h>
#include <xError.h>
#include <stdint.h>
#include <stdio.h>
#define CHECK(expr) do { \
if (!(expr)) { \
fprintf(stderr, "CHECK failed at %s:%d: %s\n", __FILE__, __LINE__, #expr); \
return 1; \
} \
} while (0)
static int check_general_errno(void)
{
GeneralMsg_s genMsg;
genMsg.errStatus = zOK;
genMsg.errStatusSetter = NULL;
LB_SetErrno(&genMsg, zERR_FAILURE, "first");
CHECK(genMsg.errStatus == zERR_FAILURE);
CHECK(genMsg.errStatusSetter != NULL);
LB_SetErrno(&genMsg, zERR_NO_MEMORY, "oom");
CHECK(genMsg.errStatus == zERR_NO_MEMORY);
LB_SetErrno(&genMsg, zERR_FAILURE, "ignored");
CHECK(genMsg.errStatus == zERR_NO_MEMORY);
LB_ForceSetErrnoWithWhere(&genMsg, zERR_FAILURE, "forced");
CHECK(genMsg.errStatus == zERR_FAILURE);
CHECK(genMsg.errStatusSetter != NULL);
return 0;
}
static int check_msg_status(void)
{
Msg_s msg;
msg.sys.status = zOK;
msg.sys.where = 0;
MSG_SetStatus(&msg, zERR_FAILURE, "first");
CHECK(msg.sys.status == zERR_FAILURE);
CHECK(msg.sys.where != 0);
MSG_SetStatus(&msg, zERR_OUT_OF_SPACE, "space");
CHECK(msg.sys.status == zERR_OUT_OF_SPACE);
MSG_SetStatus(&msg, zERR_FAILURE, "ignored");
CHECK(msg.sys.status == zERR_OUT_OF_SPACE);
return 0;
}
int main(void)
{
if (check_general_errno() != 0) {
return 1;
}
if (check_msg_status() != 0) {
return 1;
}
return 0;
}