0642 nwnss: import residual COMN backend providers

This commit is contained in:
ChatGPT
2026-06-16 16:45:15 +00:00
committed by Mario Fetka
parent fbe4b33bec
commit 54b87b31f9
40 changed files with 27630 additions and 0 deletions

View File

@@ -0,0 +1,78 @@
/****************************************************************************
|
| (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) module
|
|---------------------------------------------------------------------------
|
| $Author: taysom $
| $Date: 2004-12-31 01:10:58 +0530 (Fri, 31 Dec 2004) $
|
| $RCSfile$
| $Revision: 465 $
|
|---------------------------------------------------------------------------
| This module is used to:
| NSS Library routine
|
| 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 _PSSLIB_H_
#define _PSSLIB_H_
#ifndef _OMNI_H_
#include <omni.h>
#endif
/* Pre-declare the following structure(s) */
struct ScreenStruct;
#ifdef __cplusplus
extern "C" {
#endif
/* use rand in STDLIB.H
extern void seed(long seed);
extern NINT rnd(NINT range);
*/
extern void SetStdioScreenID(
struct ScreenStruct *screenID);
extern NINT GetInstLen(
BYTE *instruction,
NINT *instType);
#define INSTTYPE_NORMAL 0
#define INSTTYPE_PCRELATIVE32 1
#define INSTTYPE_PCRELATIVE16 2
#define INSTTYPE_PCRELATIVE8 3
#ifdef __cplusplus
}
#endif
#endif

120
include/nwnss/include/mal.h Normal file
View File

@@ -0,0 +1,120 @@
/****************************************************************************
|
| (C) Copyright 1995 - 2000 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
|
|***************************************************************************
|
| Novell Storage Services (NSS) support module
|
|---------------------------------------------------------------------------
|
| $Author: vandana $
| $Date: 2007-05-04 03:01:42 +0530 (Fri, 04 May 2007) $
|
| $RCSfile$
| $Revision: 1971 $
|
|---------------------------------------------------------------------------
| This module is used to:
|
|
|
| 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 _MAL_H_
#define _MAL_H_
#ifdef __cplusplus
extern "C" {
#endif
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*- MAL basic defines
|
| These are basic defines to determine the size of common items
|
+-------------------------------------------------------------------------*/
#define MAL_ONEKBYTES 1024
#define MAL_ONEMEG 0x00100000
#define MAL_BLKSHFT512 9
#define MAL_BLKSHFT4K 12
#define MAL_BLKSHFT64K 16
#define MAL_BUFSZ512 (1 << MAL_BLKSHFT512)
#define MAL_BUFSZ4K (1 << MAL_BLKSHFT4K)
#define MAL_BUFSZ64K (1 << MAL_BLKSHFT64K)
#define MAL_DEFAULTBLKSIZE 4096
#define MAL_STDUNITSIZE 512
#define MAL_UNITSPER1MEG 2048
#define MAL_BLKSPER1MEG 256
#define MAL_UNITSPERBLK 8
#define POOL_MAXNAME 64
#define MAL_MAXNAME 64 /*- max. size of a pool name -*/
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
/*- Deposit Message Type Defined
|
|
+-------------------------------------------------------------------------*/
typedef struct Deposit_s
{
struct block_device *dp_dev; /* Linux block device structure */
LONG unitsize; /*- smallest IO unit size in bytes -*/
QUAD sizeinunits; /*- number of units for this storage deposit -*/
LONG sizeinmeg; /*- number of meg for this storage deposit -*/
GUID_t guid; /*- GUID (128 bits) when storage was created -*/
void *dp_inode; /* pointer to a root inode on the pool */
unicode_t name[MAL_MAXNAME];
unicode_t snapname[MAL_MAXNAME];
} Deposit_s;
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
extern LONG MAL_RemoveDeposit (struct block_device *dev);
extern LONG MAL_ForwardDepositToConsumer(struct block_device *dev, LONG unitSize, char *poolName, LONG flags, char *snapname, void *inode);
#define ZLSS_DEV_FLAG_SHARED 0x00000001
#define ZLSS_DEV_FLAG_BARRIER 0x00000002
#define ZLSS_DEV_FLAG_SNAPSHOT 0x00000004
#define ZLSS_DEV_FLAG_NEW 0x00000008
extern LONG MAL_CreateDeposit (struct block_device *dev, LONG unitSize, char *poolName);
extern STATUS MAL_GetPoolNameFromDevice (struct block_device *dev, char *poolName, NINT poolNameSize);
extern STATUS ZLSS_GetPoolDev(unicode_t *uniName, struct block_device **dev);
extern STATUS ZLSS_SetPoolSize(struct block_device *dev, QUAD newSize);
extern STATUS ZLSS_SetPoolShared(struct block_device *dev, BOOL sharedstate);
#ifdef __cplusplus
}
#endif
#endif /* _MAL_H_ */

View File

@@ -43,6 +43,16 @@
#ifndef _NSSOSAPIS_H_
#define _NSSOSAPIS_H_
#ifdef MARS_NWE_NWNSS_USERSPACE
#ifndef KERNEL_VERSION
#define KERNEL_VERSION(_major, _minor, _patch) \
(((_major) << 16) + ((_minor) << 8) + (_patch))
#endif
#ifndef LINUX_VERSION_CODE
#define LINUX_VERSION_CODE 0
#endif
#endif
#ifndef _ZOMNI_H_
# include <zOmni.h>
#endif

View File

@@ -0,0 +1,143 @@
/****************************************************************************
|
| (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: randys $
| $Date: 2005-08-05 01:19:13 +0530 (Fri, 05 Aug 2005) $
|
| $RCSfile$
| $Revision: 1166 $
|
|---------------------------------------------------------------------------
| This module is used to:
| Defines structures used to cache file names in memory
+-------------------------------------------------------------------------*/
#ifndef _ZASAUTHCACHE_H_
#define _ZASAUTHCACHE_H_
#ifndef _OMNI_H_
#include <omni.h>
#endif
#ifndef _MSGGEN_H_
#include <msgGen.h>
#endif
#ifndef _ZASAUTHMODEL_H_
#include "zasAuthModel.h"
#endif
/*-------------------------------------------------------------------------
* This is the authorization cache node structure. One of these structures is
* maintained in memory for each entry in the cache.
*-------------------------------------------------------------------------*/
typedef struct EffectiveACL_s
{ /* This is is the effective ACL structure used by the authorization cache. */
LONG numEntries; /* number of entries in use */
ACLEntry_s entry[1];
} EffectiveACL_s;
typedef struct AuthCacheNode_s
{
LONG signature; /* identifing field for entry */
DQlink_t hashLink; /* hash list link field */
DQlink_t LRUlink; /* LRU link field */
NINT hashValue; /* computed full hash for this entry */
DomainID_t domainID; /* directory services domain for this entry */
EffectiveACL_s EACL; /* effective ACL being cached */
} AuthCacheNode_s;
/*-------------------------------------------------------------------------
* This is the control structure for the AuthCache. The AuthCache is
* global for the entire system.
*-------------------------------------------------------------------------*/
typedef struct AuthCacheCtrl_s
{
Latch_s latch; /* latch to control changes in this structure */
NINT activationCount; /* number of volumes using the cache */
NINT hashMask; /* and MASK used to index into hash */
DQhead_t (*hash)[]; /* pointer to hash array */
DQhead_t LRUqueue; /* head of the Least Recently Used queue */
NINT maxEntries; /* max allowed entries are in the cache */
NINT numEntries; /* number of entries in the cache */
NINT signatureCount; /* the count used to create signatures */
NINT resetCount; /* this count is incremented each time the
cache is reset. It should be incremented
before the actual reset occurs */
} AuthCacheCtrl_s;
extern AuthCacheCtrl_s AuthCache; /* control head for the name hash*/
/*-------------------------------------------------------------------------
*
* DEFINES
*
*-------------------------------------------------------------------------*/
#define MIN_AUTH_CACHE_SIZE 16 /* The minimum number of entries in the */
/* authorization cache. */
#define DEFAULT_AUTH_CACHE_SIZE 1024 /* The maximum number of entries in the */
/* authorization cache. */
#define MAX_AUTH_CACHE_SIZE 50000 /* The maximum number of entries in the */
/* authorization cache. */
#define HASH_TABLE_SIZE 1024 /* Size of the hash table (must be a power of 2)*/
/* If you change this size change the hash algorithm */
#define EACL_SIZE(numACLs) \
(sizeof(AuthCacheNode_s) + (sizeof(ACLEntry_s) * ((numACLs) - 1)))
#define EACL_GROW_AMOUNT 10
/*-------------------------------------------------------------------------
* Functions for manipulating the name cache.
*-------------------------------------------------------------------------*/
extern STATUS ZAS_CacheInit(
GeneralMsg_s *genMsg);
extern void ZAS_CacheUninit(void);
extern AuthCacheNode_s *ZAS_GetEACLCacheEntry(
NINT cacheIndex,
NINT signature);
extern AuthCacheNode_s *ZAS_AddEACLCacheEntry(
struct AuthCacheNode_s *newEntry,
NINT inputResetCount,
LONG *cacheIndex);
extern void ZAS_RemoveEACLCacheEntry(
NINT cacheIndex,
NINT signature);
#if NSS_DEBUG IS_ENABLED
extern void ZAS_DisplayCache(void);
extern NINT AuthResets;
extern NINT AuthPartialResets;
#endif
#endif /* _ZASAUTHCACH_H_ */

View File

@@ -0,0 +1,172 @@
/****************************************************************************
|
| (C) Copyright 2003 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
|
|***************************************************************************
|
| Novell Storage Services (NSS) Initialization module
|
|---------------------------------------------------------------------------
|
| $Author: taysom $
| $Date: 2004-12-31 01:10:58 +0530 (Fri, 31 Dec 2004) $
|
| $RCSfile$
| $Revision: 465 $
|
|---------------------------------------------------------------------------
| This module is used to:
| This module defines the unix authorization system.
+-------------------------------------------------------------------------*/
#ifndef _UXASAUTHMODEL_H_
#define _UXASAUTHMODEL_H_
#ifndef _OMNI_H_
#include <omni.h>
#endif
#ifndef _LATCH_H_
#include <latch.h>
#endif
#ifndef _COMNBEASTS_H_
#include "comnBeasts.h"
#endif
#ifndef _COMNAUTHORIZE_H_
#include "comnAuthorize.h"
#endif
/*-------------------------------------------------------------------------
* Defines
*-------------------------------------------------------------------------*/
#define UXAS_CURRENT_AUTH_VERSION 1
/* Unix mode bit definitions */
#define UX_IXOTH 0x0001 /* other - execute */
#define UX_IWOTH 0x0002 /* other - write */
#define UX_IROTH 0x0004 /* other - read */
#define UX_IXGRP 0x0010 /* group - execute */
#define UX_IWGRP 0x0020 /* group - write */
#define UX_IRGRP 0x0040 /* group - read */
#define UX_IXUSR 0x0100 /* owner - execute */
#define UX_IWUSR 0x0200 /* owner - write */
#define UX_IRUSR 0x0400 /* owner - read */
#define UX_ISVTX 0x1000 /* sticky bit */
#define UX_ISGID 0x2000 /* set group ID on execution */
#define UX_ISUID 0x4000 /* set user ID on execution */
#define UX_IRWXO 0x0007 /* mask for "other" */
#define UX_IRWXG 0x0070 /* mask for "group" */
#define UX_IRWXU 0x0700 /* mask for "owner" */
#define UX_IX 0x0001 /* execute */
#define UX_IW 0x0002 /* write */
#define UX_IR 0x0004 /* read */
#define UX_IMO 0 /* shift factor for other/world */
#define UX_IMG 4 /* shift factor for group */
#define UX_IMU 8 /* shift factor for user/owner */
/*-------------------------------------------------------------------------
* Macros
*-------------------------------------------------------------------------*/
typedef struct UXASPersistentAuthInfo_s
{ /* this is a space for the z authorization system to use */
WORD version; /* the version of the authorization layout */
WORD extra1; /* alignment space */
LONG mode; /* see above (UX_*) */
UserID_t groupID;
LONG unused[8];
} NSS_MEDIA_STRUCTURE(UXASPersistentAuthInfo_s,unused[8]) UXASPersistentAuthInfo_s;
typedef struct UXASAuthorizeInfo_s
{ /* Unix authorization model */
UXASPersistentAuthInfo_s p;
} UXASAuthorizeInfo_s;
/*-------------------------------------------------------------------------
* Public Structures for the authorization model
*-------------------------------------------------------------------------*/
extern struct AuthModelOps_s UXASAuthorizeModelOps;
extern NINT UXASAuthorizeStarted;
extern NINT UX_InitialMode;
/*-------------------------------------------------------------------------
*
* Function prototypes for the Unix authorization model
*
*-------------------------------------------------------------------------*/
STATUS UXAS_Startup(void);
void UXAS_Shutdown(void);
STATUS UXAUTH_ConstructAuthBeast(
struct GeneralMsg_s *genMsg,
struct AuthBeast_s *authBeast);
void UXAUTH_DestructAuthBeast(
struct AuthBeast_s *authBeast);
NINT UXAUTH_PackedSize(
struct AuthBeast_s *authBeast);
BYTE *UXAUTH_PackAuthBeast(
struct AuthBeast_s *authBeast,
BYTE *storeBuffer);
void UXAUTH_NoPackAuthBeastCleanup(
struct AuthBeast_s *authBeast);
BYTE *UXAUTH_UnpackAuthBeast(
struct GeneralMsg_s *genMsg,
struct AuthBeast_s *authBeast,
BYTE *storeBuffer);
STATUS UXAS_ChangeOwner(
struct GeneralMsg_s *genMsg,
struct NamingMsg_s *nameMsg,
struct AuthBeast_s *beast,
UserID_t *newOwner);
STATUS UXAS_ChangeGroup(
struct AuthBeast_s *beast,
UserID_t *newGroup);
STATUS UXAS_ChangeMode(
struct AuthBeast_s *beast,
NINT mode);
STATUS UXAS_GetAuthInfo(
struct AuthBeast_s *beast,
UserID_t *groupID,
NINT *mode);
void UXAS_StoreIDInGUID(
NINT id,
UserID_t *guid);
NINT UX_GetEffectivePermissions(
struct AuthBeast_s *authBeast,
UserID_t *IDs,
NINT numIDs,
NINT *mode);
#endif /* _ZASAUTHMODL_H_ */

View File

@@ -0,0 +1,56 @@
/****************************************************************************
|
| (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 Advance File Services (NSS) module
|
|---------------------------------------------------------------------------
|
| $Author: vandana $
| $Date: 2006-10-31 02:59:05 +0530 (Tue, 31 Oct 2006) $
|
| $RCSfile$
| $Revision: 1585 $
|
|---------------------------------------------------------------------------
| This module is used to:
| Defines to be used with the NFS APIs for the NFS Semantic Agent.
|
| For compelete documentation, see "NFS Illustrated" by Brent Callaghan,
| Addison-Wesley, 2000, ISBN 0-201-32570-5.
|
| 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 _NFSAPIS_H_
#define _NFSAPIS_H_
typedef struct NFSHandle_s
{
Zid_t zid; /* zid of the file */
VolumeID_t volID; /* Id of the volume (a GUID) */
} NFSHandle_s;
#endif

View File

@@ -0,0 +1,265 @@
/****************************************************************************
|
| (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) module
|
|---------------------------------------------------------------------------
|
| $Author: taysom $
| $Date: 2004-12-31 01:10:58 +0530 (Fri, 31 Dec 2004) $
|
| $RCSfile$
| $Revision: 465 $
|
|---------------------------------------------------------------------------
| This module is used to:
| Define data structures used by NFS Lock Manager (NLM).
|
| WARNING! WARNING! WARNING! WARNNG! WARNING! WARNING! WARNING! WARNING!
|
| This header file should ONLY be used for NSS internal development.
+-------------------------------------------------------------------------*/
#ifndef _NFSLOCKS_H_
#define _NFSLOCKS_H_
#ifndef _STDDEF_H_
# include <stddef.h>
#endif
#ifndef _OMNI_H_
# include <omni.h>
#endif
#ifndef _NFSAPIS_H_
# include <nfsAPIs.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef enum LkMgrStat_t
{
LKMGR_GRANTED,
LKMGR_DENIED,
LKMGR_DENIED_NOLOCKS,
LKMGR_BLOCKED,
LKMGR_DENIED_GRACE_PERIOD,
LKMGR_DEADLCK,
LKMGR_ROFS,
LKMGR_STALE_FH,
LKMGR_FBIG,
LKMGR_FAILED
} LkMgrStat_t;
typedef enum FshMode_t
{
FSM_DN, /* Deny None */
FSM_DR, /* Deny Read */
FSM_DW, /* Deny Write */
FSM_DRW /* Deny Read and Write */
} FshMode_t;
typedef enum FshAccess_t
{
FSA_NONE, /* No access */
FSA_R, /* Read access */
FSA_W, /* Write access */
FSA_RW /* Read/Write access */
} FshAccess_t;
typedef struct NetObj_s
{
LONG length;
LONG data[1]; /* Opaque data, variable length */
} NetObj_s;
/*
* In the NLM version 3 protocol, the length and offset are 32 bits wide, while
* they are 64 bits wide in the NLM version 4 protocol. NLM version 3 should
* cast them to 64 bits.
*/
typedef struct LkMgrLock_s
{
BYTE *callerName; /* NULL terminated byte string, case insensitive */
NFSHandle_s *fh;
NetObj_s *oh;
LONG svid;
QUAD offset;
QUAD len;
} LkMgrLock_s;
/*----------------------------------------------------------------------------------*
*----------------------------------------------------------------------------------*/
/************************************************************************************
* Checks if a lock is available to the client. *
* Input: *
* testAccess: TRUE: Test if the client could get access (sharable) to the lock*
* FALSE: Test if there's a lock existing in the requested region *
* alock: the monitored lock that is being tested. *
* Output (only will be filled when status is LKMGR_DENIED): *
* isExclusive:TRUE if the conflicting lock is exclusively held *
* svid: the process id of the lock holder. If the lock holder is a NCP/ *
* Windows client, it will be set to 0. *
* oh: a pointer to lock holder's owner. If the lock holder is a NCP/ *
* Windows client, it will be set to NULL. *
* offset: the conflicting lock's byte offset *
* len: length, in bytes of the conflicting lock. *
************************************************************************************/
STATUS LkMgrTest(
BOOL testAccess,
LkMgrLock_s *alock,
BOOL *isExclusive,
LONG *svid,
NetObj_s **oh,
QUAD *offset,
QUAD *len);
/************************************************************************************
* Creates a locked byte range on a file *
* Note: *
* 1: If a callback is supplied, the granted lock (either granted immediately or *
* blocked then granted later) will always be returned through callback *
* function, while this function returns LKMGR_BLOCKED. This also implies that *
* if input parameter "block" is TRUE, callback is a valid value. *
* 2: This function will make a local copy all the necessary information. Caller *
* can release its related memory if it chooses to do so *
************************************************************************************/
STATUS LkMgrLock(
NetObj_s *cookie, /* NULL terminated byte string */
BOOL block,
BOOL isExclusive,
LkMgrLock_s *alock,
SLONG state,
NINT *callerCount,
void *callback(
STATUS status,
NetObj_s *cookie,
BOOL block,
BOOL isExclusive,
NINT callerCount,
LkMgrLock_s *alock));
/********************************************************************************
* Lock Manager will search all the locks on the requested file. *
* return: LCK_GRANTED if lock is found and removed from the waiting list *
* LCK_DENIED if lock couldn't be found from the waiting list. *
* Note: if a lock is granted after client sends the cancel request but before *
* server receives it, a LCK_DENIED will be returned. client should *
* try to call LkMgrUnlock instead *
********************************************************************************/
STATUS LkMgrCancel(
BOOL block,
BOOL isExclusive,
LkMgrLock_s *alock);
/********************************************************************************
* Lock Manager will search all the locks on the requested file. *
* return: LCK_GRANTED if lock is found and removed from the locking list *
* LCK_DENIED if lock couldn't be found from the locking list or it is *
* still in the waiting state. *
* Note: client should call this routine if it knows the lock is granted *
********************************************************************************/
STATUS LkMgrUnlock(
LkMgrLock_s *alock,
NINT *callerCount);
/********************************************************************************
* Creates a SHARE reservation on a file. *
********************************************************************************/
STATUS LkMgrShare(
BYTE *callerName, /* NULL terminated byte string */
NFSHandle_s *fh,
NetObj_s *oh,
FshMode_t mode,
FshAccess_t access);
/********************************************************************************
* Removes a SHARE reservation on a file. *
********************************************************************************/
STATUS LkMgrUnshare(
BYTE *callerName, /* NULL terminated byte string */
NFSHandle_s *fh,
NetObj_s *oh,
FshMode_t mode,
FshAccess_t access);
/********************************************************************************
* Creates a nonmonitored byte-range lock on a file. *
********************************************************************************/
STATUS LkMgrNmLock(
BOOL block,
BOOL isExclusive,
LkMgrLock_s *alock,
SLONG state);
/********************************************************************************
* Clients has lost lock state and all server locks owned by this client *
* should be freed. (This also includes to release all the share reservations *
* created by this client). *
********************************************************************************/
void LkMgrFreeAll(
BYTE *callerName); /* NULL terminated byte string */
/********************************************************************************
* Clients has lost lock state and all server locks owned by this client *
* with state lower than the specified number should be freed. (This also *
* includes to release all the share reservations created by this client). *
********************************************************************************/
void LkMgrFreeAllWithState(
BYTE *callerName, /* NULL terminated byte string */
SLONG state);
void LkMgrCleanup();
/*-------------------------------------------------------------------------------*/
void displayLkMgrStats();
void cleanupLkMgrStats();
void startLkMgrBgCleanupThread();
STATUS initLkMgr();
void uninitLkMgr();
NINT nssToLkMgrError (NINT status);
#ifdef __cplusplus
}
#endif
#endif /* _NFSLOCKS_H_ */

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1,411 @@
/****************************************************************************
|
| (C) Copyright 2004 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
|
|***************************************************************************/
LONG GenerateAuditRecord(
LONG volumeNumber,
LONG eventTypeID,
LONG connectionID, /* ID of event initiator */
LONG successFailureStatusCode,
...);
void ConvertNewTrusteeRightsToOld(
BYTE *accessRights,
BYTE macStationFlag,
LONG station,
LONG volume,
LONG directoryNumber,
LONG nameSpace);
void ConvertOldTrusteeRightsToNew(
BYTE *accessRights,
BYTE macStationFlag);
BYTE *FindLastComponent(
BYTE *componentString,
LONG componentCount);
void AlertNCPSearchMapLost(
LONG Station);
void BeginTrans(
LONG station,
LONG task,
LONG wtime,
void (*rplyf)());
LONG EndTrans(
LONG station,
LONG task);
LONG LogPRec(
LONG station,
LONG hndle,
LONG start,
LONG length,
LONG flags,
LONG wtime,
void (*rplyf)(),
...);
void LogRec(
LONG station,
LONG task,
BYTE *string,
LONG flags,
LONG wtime,
void (*rplyf)());
LONG ClearFLocks(
LONG station,
LONG task,
LONG lastset);
LONG INWReleaseFile(
LONG station,
LONG task,
LONG vol,
LONG dir);
LONG INWClearFile(
LONG station,
LONG task,
LONG vol,
LONG dir);
void LFileSet(
LONG station,
LONG task,
LONG wtime,
void (*rplyf)());
LONG RelFileSet(
LONG station,
LONG task,
LONG lastset);
void INWLogFile(
LONG station,
LONG task,
LONG vol,
LONG dir,
BYTE *filename,
LONG flags,
LONG wtime,
void (*rplyf)());
LONG OpenEAHandle(
LONG Station,
LONG Task,
LONG OpenFlags,
LONG Flags,
LONG Volume,
LONG Handle,
LONG *EAHandle);
LONG CloseEAHandle(
LONG Station,
LONG Task,
LONG eaHandle);
LONG WriteEAData(
LONG Station,
LONG Task,
LONG eaHandle,
LONG TotalDataLength,
LONG StartPosition,
LONG AccessFlag,
LONG KeySize,
BYTE *keyBuf,
LONG DataSize,
BYTE *inBuf,
LONG *BytesWritten);
LONG ReadEAData(
LONG Station,
LONG Task,
LONG eaHandle,
LONG StartPosition,
LONG InspectSize,
LONG KeySize,
BYTE *Key,
BYTE *OutBuf,
LONG *TotalEALen,
WORD *CurrentLen,
LONG *AccessFlag,
LONG MaximumDataSize);
LONG EnumEA(
LONG Station,
LONG Task,
LONG eaHandle,
LONG InfoLevel,
LONG StartPosition,
LONG InspectSize,
LONG KeySize,
BYTE *Key,
BYTE *EnumBuf,
LONG *EnumBufSize,
WORD *NextPos,
LONG *TotalDataSizeOfEAs,
LONG *TotalEAs,
WORD *CurrentEAsInReply,
LONG *TotalKeySizeOfEAs,
LONG MaximumDataSize);
LONG DupEA(
LONG Station,
LONG Task,
LONG srcTypeFlag,
LONG srcVolume,
LONG srcHandle,
LONG dstTypeFlag,
LONG dstVolume,
LONG dstHandle,
LONG *DupCount,
LONG *DupData,
LONG *DupKey);
LONG GetCurrentDiskUsedAmount(
LONG volumeNumber,
LONG trusteeID);
LONG VCStnLockStatus(
LONG station,
LONG BufferSize,
BYTE *buffer);
LONG VCStnFiles(
LONG station,
LONG buffersize,
BYTE *buffer,
LONG next);
LONG VCFileTasks(
BYTE vol,
LONG dir,
BYTE forktype,
LONG buffersize,
BYTE *buffer,
LONG next);
LONG VCStnPhyLocks(
LONG station,
BYTE vol,
LONG dir,
BYTE forktype,
LONG buffersize,
BYTE *buffer,
LONG next);
LONG VCFilePhyLocks(
BYTE vol,
LONG dir,
BYTE forktype,
LONG buffersize,
BYTE *buffer,
LONG next);
LONG VCStnLRecs(
LONG station,
LONG buffersize,
BYTE *buffer,
LONG next);
LONG VCLRecTasks(
BYTE length,
BYTE *name,
LONG buffersize,
BYTE *buffer,
LONG next);
LONG VCStnSems(
LONG station,
LONG buffersize,
BYTE *buffer,
LONG next);
LONG VCSemaphoreTasks(
LONG length,
BYTE *name,
LONG buffersize,
BYTE *buffer,
LONG next);
LONG SCreateSemaphore(
LONG station,
LONG task,
BYTE *string,
LONG initial,
BYTE *repbuf);
LONG SExamineSemaphore(
LONG station,
LONG task,
LONG semval,
BYTE *retbuf);
void SPSemaphore(
LONG station,
LONG task,
LONG semval,
LONG wtime,
void (*rplyf)());
LONG SVSemaphore(
LONG station,
LONG task,
LONG semval);
LONG SCloseSem(
LONG station,
LONG task,
LONG semval);
void LockPRecSet(
LONG station,
LONG task,
LONG flags,
LONG wtime,
void (*rplyf)());
void LRecSet(
LONG station,
LONG task,
LONG flags,
LONG wtime,
void (*rplyf)());
void MultiLFileSet(
LONG station,
LONG task,
LONG wtime,
void (*rplyf)());
LONG TTSCheck(void);
LONG TTrackOn(
LONG station,
LONG task);
LONG TTrackOff(
LONG station,
LONG task,
BYTE *retbuf);
LONG TTrackAbort(
LONG station,
LONG task);
LONG TTSCheckTransaction(
LONG referenceNumber);
LONG SetTTaskFlags(
LONG station,
LONG task,
LONG pthresh,
LONG lthresh);
LONG GTTaskFlags(
LONG station,
LONG task,
BYTE *threshrets);
LONG STTaskState(
LONG station,
LONG task,
LONG flags);
void GTTaskState(
LONG station,
LONG task,
BYTE *threshrets);
LONG SetTransFlags(
LONG station,
LONG pthresh,
LONG lthresh);
void GTransFlags(
LONG station,
BYTE *threshrets);
LONG RelPRecLocks(
LONG station,
LONG task,
LONG lastset,
LONG clrflag);
LONG ReleasePRec(
LONG station,
LONG hndle,
LONG start,
LONG length,
LONG clrflag);
void ResetStation(
LONG station,
LONG task);
void ClearTemporaryDirectoryHandles(
LONG Station,
LONG Task);
LONG ClearRLocks(
LONG station,
LONG task,
LONG lastset);
LONG RelRecSet(
LONG station,
LONG task,
LONG lastset);
LONG ReleaseRecord(
LONG station,
LONG task,
BYTE *string);
LONG UnlockRec(
LONG station,
LONG task,
BYTE *string);
LONG GetFileStatusInformation(
LONG Station,
LONG Task,
WORD Index,
LONG SourceBase,
LONG SearchAttributes,
BYTE *ModifierString,
BYTE *ReplyArea);
LONG SetFileStatusInformation(
LONG Station,
LONG Task,
LONG Base,
BYTE *ModifierString,
BYTE SearchAttributes,
WORD fileAttributes,
LONG CreationDate,
LONG LastAccessedDate,
LONG LastUpdatedDateAndTime,
LONG OwnerID);

View File

@@ -0,0 +1 @@

View File

@@ -169,6 +169,29 @@ add_library(nwnss SHARED
comn/namespace/extAttrNSpace.c
comn/namespace/macNSpace.c
nss/msg/msg.c
nssStartupNameGlobals.c
library/misc/lbVolume.c
library/os/currentTime.c
comn/common/volStartup.c
comn/common/comnDataStream.c
comn/common/nameLookup.c
comn/common/comnRename.c
comn/common/comnWild.c
comn/common/mgmtVol.c
comn/common/mgmtFiles.c
comn/common/cSAmanager.c
comn/common/cSAcache.c
comn/common/comnEFL.c
comn/common/comnLog.c
comn/common/checker.c
comn/common/ndpIdBrokerShared.c
comn/common/sysimpUserland.c
comn/main/comnCmdline.c
comn/authsys/authorize.c
comn/compression/cmActivity.c
comn/compression/cmBgCompress.c
comn/compression/cmAlgoMan.c
comn/compression/cmControl.c
comn/common/temporaryComnStubs.c
comn/namespace/dosNSWild.c
nss/cache/asyncio.c

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,163 @@
/****************************************************************************
|
| (C) Copyright 2002 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: vandana $
| $Date: 2005-08-10 01:03:51 +0530 (Wed, 10 Aug 2005) $
|
| $RCSfile$
| $Revision: 1177 $
|
|---------------------------------------------------------------------------
+-------------------------------------------------------------------------*/
#include <linux/module.h>
#include <stdint.h>
#include <comnPublics.h>
#include <volume.h>
#include <msg.h>
#include "xMsg.h"
#include "csa.h"
/*****************************************************************************
*
****************************************************************************/
void CSA_MsgSendAll(
Volume_s *volume,
xMsg_s *msg,
NINT method)
{
CsaVolumeDoor_s *csaVolObject;
CsaVolumeDoor_s *prevCsaVolObject;
if (CSA_SLAVE_VOLUMES_FOUND(volume))
{
DQ_FOREACH_NONEXT(&volume->v_csaVolInfo->CVI_csaVolumeDoorHead,
csaVolObject, CsaVolumeDoor_s, csaVolumeDoorLink)
{
MSG_USE_DOOR(&csaVolObject->door);
MSG_Send(csaVolObject->xlssVolumeKey, method, (Msg_s *)msg);
DQ_FOREACH_NEXT(prevCsaVolObject, csaVolObject,
CsaVolumeDoor_s, csaVolumeDoorLink);
/*** WARNING - csaVolumeDoorLink now points to
*** the next item. Generally, code below this
*** should only be 'freeing' prevCsaVolObject.
***/
MSG_RELEASE_DOOR(&prevCsaVolObject->door);
}
}
return;
}
/*****************************************************************************
*
****************************************************************************/
void CSA_RemoveNameCacheEntry(
Volume_s *volume,
Zid_t parentZid,
NINT nameSpaceMask,
NINT nameType,
unicode_t *uniName,
NINT nsFlag)
{
xMsg_s msg;
CSA_NameCacheInvalidateMsg_s *csaPacket =
&msg.body.nameCacheInvalidate.csaPacket;
xMSG_INIT( &msg );
csaPacket->CNCM_parentZid = parentZid;
csaPacket->CNCM_nameSpaceMask = nameSpaceMask;
csaPacket->CNCM_nameType = nameType;
csaPacket->CNCM_nsFlag = nsFlag;
msg.sys.data[0].start = (QUAD)(uintptr_t)uniName;
msg.sys.data[0].length = (unilen(uniName) + 1) * sizeof(unicode_t);
msg.sys.numDataAreas++;
msg.sys.readMask = 0x01;
CSA_MsgSendAll(volume, &msg, XLSS_NAME_CACHE_CLEANUP);
return;
}
/*****************************************************************************
*
****************************************************************************/
void CSA_InvalidateAuthCache(
GeneralMsg_s *genMsg,
UserID_t *trusteeID,
BOOL entireCache)
{
xMsg_s msg;
CSA_AuthCacheInvalidateMsg_s *csaPacket =
&msg.body.authCacheInvalidate.csaPacket;
Volume_s *volume;
xMSG_INIT( &msg );
csaPacket->CACM_trusteeID = *trusteeID;
csaPacket->CACM_entireCache = entireCache;
SET_FOREACHBLOCKING(&NSSMasterVolumeList, volume, Volume_s, masterVolLink)
{
if (CSA_SLAVE_VOLUMES_FOUND(volume))
{
COMN_USE_BEAST(&volume->VOLroot);
if (COMN_LockVolumeActive(genMsg, volume, FALSE) != zOK)
{
COMN_Release(&volume);
ClearErrno(genMsg);
goto continueWithNextVolume;
}
CSA_MsgSendAll(volume, &msg, XLSS_AUTH_CACHE_CLEANUP);
COMN_UnlockVolumeActive(volume, FALSE);
COMN_Release(&volume);
}
continueWithNextVolume:
SET_FOREACHBLOCKINGEND(&NSSMasterVolumeList, volume, Volume_s,
masterVolLink)
}
return;
}
/*****************************************************************************
*
****************************************************************************/
void CSA_NotifyAllSlavesSyncd(
Volume_s *volume)
{
xMsg_s msg;
xMSG_INIT( &msg );
CSA_MsgSendAll(volume, &msg, XLSS_ALL_SLAVES_SYNCD);
return;
}

View File

@@ -0,0 +1,517 @@
/****************************************************************************
|
| (C) Copyright 1995-1999 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 Loadable Storage Services (LSS) module
|
|---------------------------------------------------------------------------
|
| $Author: vandana $
| $Date: 2005-08-10 01:03:51 +0530 (Wed, 10 Aug 2005) $
|
| $RCSfile$
| $Revision: 1177 $
|
|---------------------------------------------------------------------------
| This module is used to:
| Provide startup code for Cluster Semantic Agent
+-------------------------------------------------------------------------*/
#include <linux/module.h>
#include <stdlib.h>
#include <comnPublics.h>
#include <neb.h>
#include <eventSys.h>
#include <zEvent.h>
#include <zFriends.h>
#include <msgGen.h>
#include <xMsg.h>
#include <switchboard.h>
#include <pssStartup.h>
#include "csa.h"
#include "csaLease.h"
#include "guid.h"
/*
* Setup IPC
*/
typedef struct CsaMsgType_s
{
mTypeHeader_s hdr;
statusfunc_t method[CSA_MSG_NUM_METHODS];
} CsaMsgType_s;
typedef statusfunc_t CM_t;
extern STATUS CsaObjectDestruct(CsaMsgDoor_s *volObject);
extern STATUS CsaVolumeObjectDestruct(CsaVolumeDoor_s *volObject);
ADDR CSA_ConsumerIDExit;
BOOL CSA_StartupCompleted = TRUE;
CsamManager_s CsaMsgMgr = { 0 };
CsaMsgType_s CsaMsgType =
{
MSG_INIT_TYPE("CsaMasterVolume", &DoorType.hdr, sizeof(CsaMsgDoor_s),
CSA_MSG_NUM_METHODS,
NULL, NULL, CsaObjectDestruct, NULL, MSG_BreakDoor),
{
(CM_t)CSA_VolNotifyMsg, /* CSA_VOL_NOTIFY */
(CM_t)CSA_VolGetAuthModelIDMsg, /* CSA_VOL_GET_AUTH_ID */
}
};
CsaVolumeType_s CsaVolumeType =
{
MSG_INIT_TYPE("CsaVolume", &DoorType.hdr, sizeof(CsaVolumeDoor_s),
CSA_VOL_NUM_METHODS,
NULL, NULL, CsaVolumeObjectDestruct, NULL, MSG_BreakDoor),
{
(CM_t)CSA_VOL_GetBeastFromVolumeMsg, /* CSA_GET_BEAST */
(CM_t)CSA_VOL_WildcardLookupMsg, /* CSA_WILD_LOOKUP */
(CM_t)CSA_VOL_LookupByNameInDirectoryMsg, /* CSA_LOOKUP_NAME */
(CM_t)CSA_VOL_GetStorageInfoMsg, /* CSA_GET_STORAGE_INFO */
(CM_t)CSA_VOL_IsBlockInBeastMsg, /* CSA_IS_BLOCK_IN_BEAST */
(CM_t)CSA_VOL_GetFileBlkMsg, /* CSA_GET_FILE_BLK */
(CM_t)CSA_VOL_AsyncReadFileBlkMsg, /* CSA_ASYNC_READ_BLK */
(CM_t)CSA_VOL_GetExtentListMsg, /* CSA_GET_EXTENT_LIST */
(CM_t)CSA_VOL_IsDirectoryEmptyMsg, /* CSA_IS_DIR_EMPTY */
(CM_t)CSA_VOL_GetPhysicalExtentMsg, /* CSA_GET_PHY_EXTENT */
(CM_t)CSA_VOL_DioReadUnitsMsg, /* CSA_DIO_READ */
(CM_t)CSA_SearchMapCleanupMsg, /* CSA_SMAP_CLEANUP */
(CM_t)CSA_BeastLeaseTossMsg, /* CSA_BEAST_LEASE_TOSS */
(CM_t)CSA_ReconnectNotifyMsg, /* CSA_RECONNECT_NOTIFY */
(CM_t)CSA_BeastLeaseRecreateMsg, /* CSA_BEAST_LEASE_RECREATE */
(CM_t)CSA_SearchMapReestablishMsg, /* CSA_SMAP_REESTABLISH */
(CM_t)CSA_SearchMapCleanupAllMsg, /* CSA_SMAP_CLEANUP_ALL */
(CM_t)CSA_AccessLeaseOpenMsg, /* CSA_ACCESS_LEASE_OPEN */
(CM_t)CSA_AccessLeaseCloseMsg, /* CSA_ACCESS_LEASE_CLOSE */
(CM_t)CSA_AccessLeaseCleanupAllMsg, /* CSA_ACCESS_LEASE_CLEANUP_ALL */
}
};
STATUS CSA_SupplyVolName (unicode_t *name, VolumeID_t *guid)
{
STATUS rc;
GeneralMsg_s genMsg;
Key_t csaMsgKey;
CsaMsgDoor_s *volObject;
Volume_s *volume;
ASSERT_MPKNSS_LOCK();
volObject = MSG_CreateDoor(&CsaMsgType.hdr, CsaMsgMgr.mgr, 0, &csaMsgKey);
if (volObject == NULL)
{
return zFAILURE;
}
volObject->name = malloc((unilen(name) + 1) * sizeof(unicode_t));
if (volObject->name == NULL)
{
goto errorReturn;
}
unicpy(volObject->name, name);
volObject->volumeID = *guid;
COMN_SETUP_GENERAL_MSG_NO_CONNECTION_RESOLVE(&genMsg);
volume = COMN_VolumeIDLookup(&genMsg, guid, FALSE);
if (volume == NULL)
{
goto errorReturn;
}
volObject->volume = volume;
rc = SWBD_SupplyKey(CsaMsgMgr.client, name, csaMsgKey);
if (rc)
{
goto errorReturn;
}
return zOK;
errorReturn:
MSG_DestroyKey(csaMsgKey);
return zFAILURE;
}
BOOL CSA_matchCleanup ( mDoor_s *door, VolumeID_t *guid )
{
CsaMsgDoor_s *volDoor = (CsaMsgDoor_s *)door;
if (LB_GUIDCompare(&volDoor->volumeID, guid) == 0)
{
/* This will cause the object to be destroyed */
return TRUE;
}
return FALSE;
}
void CSA_SupplyVolCleanup( VolumeID_t *guid)
{
MSG_BreakSetOfDoors(&CsaMsgType.hdr, CSA_matchCleanup, guid);
}
LONG CSA_ChangeVolStateExit (struct EventBlock *evBlk)
{
EventChangeVolStateExit_s *data;
Volume_s *volume;
GeneralMsg_s genMsg;
CsaVolumeDoor_s *csaVolObject;
data = (EventChangeVolStateExit_s *)evBlk->EBEventData;
if (data->oldState == data->newState)
{
return 0;
}
// if (data->newState == zVOLSTATE_ACTIVE)
// {
// /*
// * We just had a volume come on line, advertise it in
// * the switchboard
// */
// rc = xVolumeGUIDToName( &data->volID, volName, zMAX_COMPONENT_NAME);
// if (rc)
// {
// return 0;
// }
// MPKNSS_LOCK();
// rc = CSA_SupplyVolName(volName, &data->volID);
// MPKNSS_UNLOCK();
// }
// else
if (data->newState != zVOLSTATE_ACTIVE)
{
MPKNSS_LOCK();
COMN_SETUP_GENERAL_MSG_NO_CONNECTION_RESOLVE(&genMsg);
volume = COMN_VolumeIDLookup(&genMsg, &data->volID, FALSE);
if (volume != NULL)
{
if (CSA_SLAVE_VOLUMES_FOUND(volume))
{
while (1)
{
DQ_DEQ( &volume->v_csaVolInfo->CVI_csaVolumeDoorHead,
csaVolObject, CsaVolumeDoor_s, csaVolumeDoorLink);
if (csaVolObject == NULL)
{
break;
}
MSG_BreakDoor(&csaVolObject->door);
}
if (volume->v_csaVolInfo->CVI_volume != NULL)
{
zASSERT(volume == volume->v_csaVolInfo->CVI_volume);
COMN_Release(&volume->v_csaVolInfo->CVI_volume);
}
}
COMN_Release(&volume);
}
CSA_SupplyVolCleanup(&data->volID);
MPKNSS_UNLOCK();
}
return 0;
}
STATUS CSA_RegisterForVolumeEvents (void)
{
struct ConsumerRegistrationInfo consumerRegInfo;
ASSERT_MPKNSS_LOCK();
/* register for EVENT_ChangeVolState_Exit */
consumerRegInfo.CRIVersion = NEB_CONSUMER_VERSION1;
consumerRegInfo.CRIConsumerName = MSGNot("NSS.cSA");
consumerRegInfo.CRIEventFlags = 0;
consumerRegInfo.CRIOwnerID = CMN_ModuleHandle;
consumerRegInfo.CRIConsumerESR = 0;
consumerRegInfo.CRISecurityToken = 0;
consumerRegInfo.CRIConsumerFlags = 0;
consumerRegInfo.CRIFilterName = 0;
consumerRegInfo.CRIFilterDataLength = 0;
consumerRegInfo.CRIFilterData = 0;
consumerRegInfo.CRIConsumerCallback = (void *)CSA_ChangeVolStateExit;
consumerRegInfo.CRIOrder = 0;
consumerRegInfo.CRIConsumerType = SYNCHRONOUS_CONSUMER;
consumerRegInfo.CRIEventName = MSGNot("NSS.ChangeVolState.Exit");
consumerRegInfo.CRIUserParameter = (void *)EVENT_ChangeVolState_Exit;
ZOS_RegisterConsumer( &consumerRegInfo);
CSA_ConsumerIDExit = (ADDR)consumerRegInfo.CRIConsumerID;
return zOK;
}
/* FixFixFix - Make this configurable */
#define WAIT_FOR_SLAVE_TIMEOUT 5
#define WAIT_FOR_SLAVE_SYNC_TIMEOUT 5
#define WAIT_FOR_SLAVE_AL_SYNC_TIMEOUT 10
#define WAIT_FOR_SLAVE_BL_SYNC_TIMEOUT 10
void CSA_CheckForSlavesAndSync(
Volume_s *volume)
{
GeneralMsg_s genMsg;
STATUS rc;
NINT timeout;
CsaVolumeDoor_s *csaVolObject;
BOOL allSyncd = FALSE;
typedef struct Stack_s {
unicode_t volName[zMAX_COMPONENT_NAME];
} Stack_s;
STACK_ALLOC();
COMN_SETUP_GENERAL_MSG_NOSA(&genMsg);
if (!(volume->VOLenabledAttributes & zATTR_CFS_MASTER))
{
STACK_FREE();
return;
}
/*
* We just had a volume come on line, advertise it in
* the switchboard
*/
rc = COMN_GetVolumeName(&genMsg, volume, aStack->volName, zMAX_COMPONENT_NAME);
if (rc)
{
STACK_FREE();
return;
}
volume->v_statusFlag |= VOL_SF_RECONNECT;
rc = CSA_SupplyVolName(aStack->volName, &volume->VOLvolumeID);
if (rc)
{
volume->v_statusFlag &= ~VOL_SF_RECONNECT;
STACK_FREE();
return;
}
timeout = WAIT_FOR_SLAVE_TIMEOUT;
while ((volume->v_csaVolInfo == NULL) && timeout--)
{
LB_delay(1000);
}
if (volume->v_csaVolInfo == NULL)
{
volume->v_statusFlag &= ~VOL_SF_RECONNECT;
STACK_FREE();
return;
}
timeout = WAIT_FOR_SLAVE_SYNC_TIMEOUT;
while (DQ_EMPTY(&volume->v_csaVolInfo->CVI_csaVolumeDoorHead))
{
LB_delay(1000);
if (--timeout == 0)
{
break;
}
}
if (timeout != 0)
{
LB_delay(5000); /* Wait for additional slaves to show up */
}
zASSERT(timeout != 0);
timeout = WAIT_FOR_SLAVE_AL_SYNC_TIMEOUT;
while (!allSyncd)
{
LB_delay(1000);
allSyncd = TRUE;
DQ_FOREACH( &volume->v_csaVolInfo->CVI_csaVolumeDoorHead, csaVolObject,
CsaVolumeDoor_s, csaVolumeDoorLink)
{
if (csaVolObject->reconnectState >= CRO_RECONNECT_STATE_SYNC_PHASE1)
{
continue;
}
else
{
allSyncd = FALSE;
}
}
if (--timeout == 0)
{
break;
}
}
zASSERT(timeout != 0);
timeout = WAIT_FOR_SLAVE_BL_SYNC_TIMEOUT;
while (!allSyncd)
{
LB_delay(1000);
allSyncd = TRUE;
DQ_FOREACH( &volume->v_csaVolInfo->CVI_csaVolumeDoorHead, csaVolObject,
CsaVolumeDoor_s, csaVolumeDoorLink)
{
if (csaVolObject->reconnectState == CRO_RECONNECT_STATE_IN_SYNC)
{
continue;
}
else
{
allSyncd = FALSE;
}
}
if (--timeout == 0)
{
break;
}
}
zASSERT(timeout != 0);
volume->v_statusFlag &= ~VOL_SF_RECONNECT;
if (allSyncd)
{
CSA_NotifyAllSlavesSyncd(volume);
}
STACK_FREE();
return;
}
STATUS CsaObjectDestruct(CsaMsgDoor_s *volObject)
{
if (volObject->volume != NULL)
{
COMN_Release(&volObject->volume);
}
if (volObject->name != NULL)
{
free(volObject->name);
volObject->name = NULL;
}
return zOK;
}
/*
* CsaVolumeObjectDestruct()-
* This is called whenever a CsaVolumeDoor_s is destroyed.
*
*/
STATUS CsaVolumeObjectDestruct(CsaVolumeDoor_s *volObject)
{
if (QMEMBER(&volObject->csaVolumeDoorLink))
{
DQ_RMV(volObject, csaVolumeDoorLink);
}
//FixFixFix Decide what to do at Clean deactivate: Should we tell the
// the slaves that we are going away or let the slave wait for reconnect
// So call MSG_DestroyKey only if we want slaves to go
// away.
/* Tell slave that we are going away */
// MSG_DestroyKey(volObject->xlssVolumeKey);
/* The only time we don't have a volume is when we failed in
* the creation of the CsaVolumeDoor_s object.
*/
if (volObject->volume != NULL)
{
/* Clean up the resources that are connected to us */
CSA_CloseFileHandlesForASlave( volObject);
CSA_SearchMapCleanupAll( volObject );
CSA_CSABeastCleanup( volObject ); /* Uses volObject->volume */
COMN_Release(&volObject->volume);
}
return zOK;
}
STATUS CSA_Ipc (void)
{
STATUS rc;
ASSERT_MPKNSS_LOCK();
CsaMsgMgr.mgr = MSG_CreateObject( &ManagerType.hdr);
if (CsaMsgMgr.mgr == NULL)
{
return zFAILURE;
}
rc = MSG_RegisterType( &CsaMsgType.hdr, CsaMsgMgr.mgr);
if (rc)
{
goto error;
}
rc = MSG_RegisterType( &CsaVolumeType.hdr, CsaMsgMgr.mgr);
if (rc)
{
goto error;
}
CsaMsgMgr.client = SWBD_NewClient("Csa");
if (CsaMsgMgr.client == NULL)
{
goto error;
}
if (CSA_RegisterForVolumeEvents())
{
goto error;
}
return zOK;
error:
MSG_KillManager(CsaMsgMgr.mgr);
return zFAILURE;
}
void CSA_Shutdown (void)
{
ASSERT_MPKNSS_LOCK();
if (CSA_StartupCompleted )
{
MSG_KillManager(CsaMsgMgr.mgr);
objCacheDestroy( &CSASearchMapCleanupList);
CSA_StartupCompleted = FALSE;
}
}
STATUS CSA_Startup(void)
{
ASSERT_MPKNSS_LOCK();
/*
* Tell the IPC we are here
*/
if (CSA_Ipc() != 0)
{
goto error;
}
if (objCacheCreate( &CSASearchMapCleanupList, "CSASearchMapCleanupList",
sizeof(SearchMapCleanupIDList_s), NULL) != zOK)
{
goto error;
}
CSA_StartupCompleted = TRUE;
return zOK;
error:
CSA_Shutdown();
return zFAILURE;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,425 @@
/****************************************************************************
|
| (C) Copyright 1995-1997 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: blarsen $
| $Date: 2006-01-21 04:09:53 +0530 (Sat, 21 Jan 2006) $
|
| $RCSfile$
| $Revision: 1315 $
|
|---------------------------------------------------------------------------
| This module is used to:
| This contains the top level internal file interfaces. All external
| interfaces call these routines.
+-------------------------------------------------------------------------*/
#include <linux/module.h>
#include <stdlib.h>
#include <string.h>
#include "comnPublics.h"
#include "xError.h"
#include "comnBeasts.h"
#include "comnDataStream.h"
#include "msgName.h"
#include "nameSpace.h"
#include "name.h"
/****************************************************************************
* COMN_InitDataStreamInfo
*****************************************************************************/
STATUS COMN_InitDataStreamInfo(
GeneralMsg_s *genMsg,
File_s *file,
NINT nameType)
{
DataStreamInfo_s *dsInfo;
SearchMsg_s searchMsg;
NameSpace_s *nameSpace;
NINT nameSpaceID;
NINT totalCount = 0;
NINT totalDataSize = 0;
NINT totalNameSize = 0;
NINT nameSize;
BOOL isUplatched = FALSE;
typedef struct Stack_s {
NamingMsg_s nameMsg;
} Stack_s;
STACK_ALLOC();
ASSERT_MPKNSS_LOCK();
ASSERT_LATCH(&file->FILEbeastLatch);
COMN_INIT_NAMING_MSG(&aStack->nameMsg);
/*---------------------------------------------------------------------------
* Return if nothing needs to be done.
*---------------------------------------------------------------------------*/
switch (nameType)
{
case zNTYPE_DATA_STREAM:
if ((file->FILEdataStreamInfo) &&
(file->FILEdataStreamInfo->dataStream.count != DSI_COUNT_INVALID))
{
STACK_FREE();
return(zOK);
}
nameSpaceID = zNSPACE_DATA_STREAM;
break;
case zNTYPE_EXTENDED_ATTRIBUTE:
if ((file->FILEdataStreamInfo) &&
(file->FILEdataStreamInfo->extAttr.count != DSI_COUNT_INVALID))
{
STACK_FREE();
return(zOK);
}
nameSpaceID = zNSPACE_EXTENDED_ATTRIBUTE;
break;
default:
zASSERT(FALSE);
SetErrno(genMsg,zERR_INVALID_NAME_TYPE);
STACK_FREE();
return(zFAILURE);
}
/*---------------------------------------------------------------------------
* When we get this far, we know that we need to calculate the appropriate
* counts based on the name type.
*
* Alloc file->dataStreamInfo structure if one does not yet exist
* Because we are playing with the file structure, even though technically
* this is a read operation, we need to get an exclusive latch on the
* beast.
*---------------------------------------------------------------------------*/
ASSERT_LATCH(&file->FILEbeastLatch);
if (IS_SLATCHED( &file->FILEbeastLatch))
{
UP_LATCH( &file->FILEbeastLatch);
isUplatched = TRUE;
}
if (file->FILEdataStreamInfo == NULL)
{
dsInfo = (DataStreamInfo_s *)zalloc(sizeof(DataStreamInfo_s));
if (dsInfo == NULL)
{
SetErrno(genMsg,zERR_NO_MEMORY);
goto cleanup_latch;
}
/* On a new one, set these to invalid until we have a successulf
* calculation to replace them with */
dsInfo->dataStream.count = DSI_COUNT_INVALID;
dsInfo->extAttr.count = DSI_COUNT_INVALID;
file->FILEdataStreamInfo = dsInfo;
}
else
{
dsInfo = file->FILEdataStreamInfo;
}
/*---------------------------------------------------------------------------
* We need to setup a nameMsg pointing to the file beast. We must manually
* "USE" all of the necessary beast pointers.
*
* NOTE - we set the latchType to XLATCHED. This is dangerous, but we are
* careful here. The cleanup code will UN_XLATCH the beast unless we
* set the latchType to NOTLATCHED before cleanup is called. We must
* not unlatch the beast in this function. That is the responsibility of
* the caller!!!!
*---------------------------------------------------------------------------*/
if ((nameSpace = COMN_NameSpaceIDLookup(genMsg, nameSpaceID)) == NULL)
{
goto cleanup_latch;
}
if (COMN_LockVolumeActive(genMsg,file->FILEvolume,FALSE) != zOK)
{
COMN_Release(&nameSpace);
goto cleanup_latch;
}
COMN_USE_BEAST(&file->FILEvolume->VOLroot);
COMN_USE_BEAST(&file->FILEroot);
COMN_USE_BEAST(&file->FILEroot);
COMN_SETUP_NAMING_MSG_FILE_BEAST_PTR(&aStack->nameMsg, file->FILEvolume,
file->FILEfirstParentZid, // cnt file->FILEfirstParentNameUniquifier,
file, NAMPMODE_FullyResolveAny, XLATCHED, /* See above comnents */
nameSpace, file->FILEfirstParentNameType, NULL);
/*---------------------------------------------------------------------------
* Setup a search message to match all sub beasts of type nameType
* and open the file to enumerate its sub beasts
*---------------------------------------------------------------------------*/
COMN_STRUCT_INIT(searchMsg);
COMN_SETUP_SEARCH_MSG (&searchMsg, -1,
SMAPOPT_32BitMode | SMAPOPT_matchAllEntries, nameType);
if (COMN_WildOpen(genMsg,&aStack->nameMsg,&searchMsg) != zOK)
{
goto cleanup_nameMsg;
}
/*---------------------------------------------------------------------------
* Read through the beast, and count every located dataStream.
*---------------------------------------------------------------------------*/
genMsg->flags |= DO_NOT_SEND_FSHOOKS;
while (COMN_WildRead(genMsg, &aStack->nameMsg, &searchMsg) == zOK)
{
/* At this point the nameMsg should contain two XLATCHED pointers,
* curFile should point to container, and curDataStream should point to
* the next dataStream to be counted. Both pointers are XLATCHED
* and have useCounts. */
if (NAME_GetFirstNameFromBeast(genMsg, aStack->nameMsg.curDataStream, 0, NULL,
NULL, NULL, &nameSize) != zOK)
{
goto cleanup_searchMap;
}
totalCount++;
totalDataSize += aStack->nameMsg.curDataStream->NAMEDeof;
totalNameSize += nameSize;
/* Put the nameMsg back to the parent file beast */
COMN_UnlatchAndRelease(&aStack->nameMsg.curDataStream, XLATCHED);
aStack->nameMsg.curDataStream = (NamedBeast_s *)aStack->nameMsg.curFile;
COMN_USE_BEAST(&aStack->nameMsg.curFile->FILEroot);
}
if (isUplatched)
{
DOWN_LATCH( &file->FILEbeastLatch);
isUplatched = FALSE;
}
genMsg->flags &= ~DO_NOT_SEND_FSHOOKS;
if (GetErrno(genMsg) == zERR_NAME_NOT_FOUND_IN_DIRECTORY)
{
ClearErrno(genMsg);
}
/*---------------------------------------------------------------------------
* Close out the wildcard search map process
*---------------------------------------------------------------------------*/
if (COMN_WildClose(genMsg,&searchMsg) != zOK)
{
goto cleanup_nameMsg;
}
/*---------------------------------------------------------------------------
* At this point, we have a valid set of counts to put into the dataStreamInfo
*---------------------------------------------------------------------------*/
switch (nameType)
{
case zNTYPE_DATA_STREAM:
dsInfo->dataStream.count = totalCount;
dsInfo->dataStream.dataSize = totalDataSize;
dsInfo->dataStream.nameSize = totalNameSize;
break;
case zNTYPE_EXTENDED_ATTRIBUTE:
dsInfo->extAttr.count = totalCount;
dsInfo->extAttr.dataSize = totalDataSize;
dsInfo->extAttr.nameSize = totalNameSize;
break;
default:
zASSERT(FALSE);
break;
}
/*---------------------------------------------------------------------------
* See above comments related to latch/unlatch of the beast in the nameMsg
*---------------------------------------------------------------------------*/
aStack->nameMsg.latchType = NOTLATCHED; /* So cleanup wont unlatch it */
COMN_CleanupNameMsg(genMsg, &aStack->nameMsg);
zASSERT(((nameType == zNTYPE_DATA_STREAM) &&
(dsInfo->dataStream.count != DSI_COUNT_INVALID)) ||
((nameType == zNTYPE_EXTENDED_ATTRIBUTE) &&
(dsInfo->extAttr.count != DSI_COUNT_INVALID)));
STACK_FREE();
return(zOK);
/*===========================================================================*/
cleanup_searchMap:
COMN_WildClose(genMsg,&searchMsg);
cleanup_nameMsg:
aStack->nameMsg.latchType = NOTLATCHED; /* So cleanup wont unlatch it */
COMN_CleanupNameMsg(genMsg, &aStack->nameMsg);
cleanup_latch:
if (isUplatched)
{
DOWN_LATCH( &file->FILEbeastLatch);
}
STACK_FREE();
return(zFAILURE);
}
/****************************************************************************
* COMN_GetDataStreamUsedSpace
*****************************************************************************/
STATUS COMN_GetDataStreamUsedSpace(
GeneralMsg_s *genMsg,
File_s *file,
NINT nameType,
BOOL adjustUsedSpace,
Xaction_s *xaction,
SQUAD *returnSize)
{
GetStorageInfo_s getStorageInfo;
SearchMsg_s searchMsg;
NameSpace_s *nameSpace;
NINT nameSpaceID;
QUAD size;
typedef struct Stack_s {
NamingMsg_s nameMsg;
} Stack_s;
STACK_ALLOC();
ASSERT_XLATCH(&file->FILEbeastLatch);
COMN_INIT_NAMING_MSG(&aStack->nameMsg);
*returnSize = 0;
/*---------------------------------------------------------------------------
* We need to setup a nameMsg pointing to the file beast. We must manually
* "USE" all of the necessary beast pointers.
*
* NOTE - we set the latchType to XLATCHED. This is dangerous, but we are
* careful here. The cleanup code will UN_XLATCH the beast unless we
* set the latchType to NOTLATCHED before cleanup is called. We must
* not unlatch the beast in this function. That is the responsibility of
* the caller!!!!
*---------------------------------------------------------------------------*/
switch (nameType)
{
case zNTYPE_DATA_STREAM:
nameSpaceID = zNSPACE_DATA_STREAM;
break;
case zNTYPE_EXTENDED_ATTRIBUTE:
nameSpaceID = zNSPACE_EXTENDED_ATTRIBUTE;
break;
default:
zASSERT(FALSE);
SetErrno(genMsg,zERR_INVALID_NAME_TYPE);
STACK_FREE();
return(zFAILURE);
}
if ((nameSpace = COMN_NameSpaceIDLookup(genMsg, nameSpaceID)) == NULL)
{
STACK_FREE();
return(zFAILURE);
}
if (COMN_LockVolumeActive(genMsg,file->FILEvolume,FALSE) != zOK)
{
COMN_Release(&nameSpace);
STACK_FREE();
return(zFAILURE);
}
COMN_USE_BEAST(&file->FILEvolume->VOLroot);
COMN_USE_BEAST(&file->FILEroot);
COMN_USE_BEAST(&file->FILEroot);
COMN_SETUP_NAMING_MSG_FILE_BEAST_PTR(&aStack->nameMsg, file->FILEvolume,
file->FILEfirstParentZid, // cnt file->FILEfirstParentNameUniquifier,
file, NAMPMODE_FullyResolveAny, XLATCHED, /* See above comments */
nameSpace, file->FILEfirstParentNameType, NULL);
/*---------------------------------------------------------------------------
* Setup a search message to match all sub beasts of type nameType
* and open the file to enumerate its sub beasts
*---------------------------------------------------------------------------*/
COMN_STRUCT_INIT(searchMsg);
COMN_SETUP_SEARCH_MSG (&searchMsg, -1,
SMAPOPT_32BitMode | SMAPOPT_matchAllEntries, nameType);
if (COMN_WildOpen(genMsg,&aStack->nameMsg,&searchMsg) != zOK)
{
goto cleanup_nameMsg;
}
/*---------------------------------------------------------------------------
* Read through the beast, and count every located dataStream.
*---------------------------------------------------------------------------*/
size = 0;
genMsg->flags |= DO_NOT_SEND_FSHOOKS;
while (COMN_WildRead(genMsg, &aStack->nameMsg, &searchMsg) == zOK)
{
/* At this point the nameMsg should contain two XLATCHED pointers,
* curFile should point to container, and curDataStream should point to
* the next dataStream to be counted. Both pointers are XLATCHED
* and have useCounts. */
if (COMN_GetStorageInfo(genMsg, aStack->nameMsg.curDataStream,
&getStorageInfo) != zOK)
{
goto cleanup_searchMap;
}
if (!(aStack->nameMsg.curDataStream->NAMEDnameFlags & NFL_BLKS_NOT_IN_PURGEABLE_CNT))
{
/* call back with size and user info if needed */
if (adjustUsedSpace)
{
VOL_AdjustUsedUserSpace(xaction,
&aStack->nameMsg.curDataStream->NAMEDroot,
-getStorageInfo.filePhysSize);
}
size += getStorageInfo.filePhysSize;
}
/* Put the nameMsg back to the parent file beast */
COMN_UnlatchAndRelease(&aStack->nameMsg.curDataStream, XLATCHED);
aStack->nameMsg.curDataStream = (NamedBeast_s *)aStack->nameMsg.curFile;
COMN_USE_BEAST(&aStack->nameMsg.curFile->FILEroot);
}
genMsg->flags &= ~DO_NOT_SEND_FSHOOKS;
if (GetErrno(genMsg) == zERR_NAME_NOT_FOUND_IN_DIRECTORY)
{
ClearErrno(genMsg);
}
/*---------------------------------------------------------------------------
* Close out the wildcard search map process
*---------------------------------------------------------------------------*/
if (COMN_WildClose(genMsg,&searchMsg) != zOK)
{
goto cleanup_nameMsg;
}
/*---------------------------------------------------------------------------
* See above comments related to latch/unlatch of the beast in the nameMsg
*---------------------------------------------------------------------------*/
aStack->nameMsg.latchType = NOTLATCHED; /* So cleanup won't unlatch it */
COMN_CleanupNameMsg(genMsg, &aStack->nameMsg);
*returnSize = size;
STACK_FREE();
return(zOK);
/*===========================================================================*/
cleanup_searchMap:
COMN_WildClose(genMsg,&searchMsg);
cleanup_nameMsg:
aStack->nameMsg.latchType = NOTLATCHED; /* So cleanup wont unlatch it */
COMN_CleanupNameMsg(genMsg, &aStack->nameMsg);
STACK_FREE();
return(zFAILURE);
}

View File

@@ -0,0 +1,324 @@
/****************************************************************************
|
| (C) Copyright 2002 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
|
|***************************************************************************
|
| Novell Storage Services (NSS) module
|
|---------------------------------------------------------------------------
|
| $Author: taysom $
| $Date: 2004-12-31 01:10:58 +0530 (Fri, 31 Dec 2004) $
|
| $RCSfile$
| $Revision: 465 $
|
|---------------------------------------------------------------------------
| This module is used to:
| Manage the event file list
+-------------------------------------------------------------------------*/
#include <procdefs.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <pssDebug.h>
#include <xError.h>
#include <xUnicode.h>
#include <comnBeasts.h>
#include <zPublics.h>
#include <guid.h>
#include <utc.h>
#include "pssStartup.h"
#include "comnPublics.h"
typedef struct EFLCheckerControl_s
{
BOOL checkerStarted;
BOOL inProgress;
OneShot_s alarm; /* Alarm for periodic background epoch checker */
FsmLite_s fsm; /* thread on which backgroung checker happens */
}EFLCheckerControl_s;
EFLCheckerControl_s eflCheckerControl = {0};
void eflCheckerStart(OneShot_s *alarm);
/*
* Seconds to elapse before the specified time of day,
* Wraps to next day if needed.
* (This routine is copied from cmBgCompress.c)
*/
NINT secondsToTimeOfDay(NINT targetTimeOfDay)
{
DOSTime_t dosTime = UTC2dosTime(GetUTCTime());
NINT hour = ((dosTime >> 11) & 0x1f);
NINT min = ((dosTime >> 5) & 0x3f);
NINT sec = ((dosTime & 0x1f) << 1);
NINT secOfDay = (hour * 60 + min) * 60 + sec;
SNINT waitSecs = targetTimeOfDay - secOfDay;
if (waitSecs < 0)
{
waitSecs += 24 * 60 * 60;
}
return waitSecs;
}
/****************************************************************************
*
* This function browses through list of volumes, and send check epoch event
* to each volume. If the volume supports EFL, it will check if any of used
* epochs hasn't been pinged for a certain amount of time and delete it if
* it is the case
*
****************************************************************************/
void checkIdleEpochs(
FsmLite_s *fsm,
ADDR unused)
{
GeneralMsg_s genMsg;
Volume_s *vol;
NINT secsToStart;
ASSERT_MPKNSS_LOCK();
COMN_SETUP_GENERAL_MSG_NOSA(&genMsg);
SET_FOREACHBLOCKING(&NSSMasterVolumeList, vol, Volume_s, masterVolLink)
{
if (!eflCheckerControl.checkerStarted)
{
break;
}
vol->VOLcomnVolOps.VOL_administerEFL(&genMsg, vol,
VOL_EFL_ADMIN_CHECK_EPOCH, NULL, NULL);
SET_FOREACHBLOCKINGEND(&NSSMasterVolumeList, vol, Volume_s, masterVolLink)
}
/* restart checker */
eflCheckerControl.inProgress = FALSE;
if (eflCheckerControl.checkerStarted)
{
secsToStart = secondsToTimeOfDay(0);
if (secsToStart)
{
secOneShot(&eflCheckerControl.alarm, secsToStart,
eflCheckerStart);
}
else
{
eflCheckerStart(&eflCheckerControl.alarm);
}
}
}
/****************************************************************************
*
* This function schedules efl checker
*
****************************************************************************/
void eflCheckerStart(OneShot_s *alarm)
{
if (!eflCheckerControl.inProgress)
{
eflCheckerControl.inProgress = TRUE;
WORK_Schedule(&eflCheckerControl.fsm, checkIdleEpochs, 0);
}
}
/****************************************************************************
*
* This function starts efl checker
*
****************************************************************************/
void startupEFLChecker()
{
NINT secsToStart;
ASSERT_MPKNSS_LOCK();
eflCheckerControl.checkerStarted = TRUE;
eflCheckerControl.inProgress = FALSE;
secsToStart = secondsToTimeOfDay(0);
if (!secsToStart)
{
/* Don't start epoch checker at the startup time */
secsToStart = 24 * 60 * 60;
}
/* set up epoch checker, let it run at mid-night */
INIT_ONESHOT(eflCheckerControl.alarm);
FSMLITE_INIT(&eflCheckerControl.fsm, "EFL checker", 1);
secOneShot(&eflCheckerControl.alarm, secsToStart,
eflCheckerStart);
}
/****************************************************************************
*
* This function inits EFL related routines. It is called by pssStartup.
*
****************************************************************************/
void EFL_Init()
{
ASSERT_MPKNSS_LOCK();
startupEFLChecker();
}
/****************************************************************************
*
* This function uninits EFL related items.
*
****************************************************************************/
void EFL_Uninit()
{
#define COMN_EFL_SHUTDOWN_SECONDS 30
NINT i;
ASSERT_MPKNSS_LOCK();
if (eflCheckerControl.checkerStarted)
{
eflCheckerControl.checkerStarted = FALSE;
i = 0;
while (eflCheckerControl.inProgress)
{
LB_delay(1000);
if (++i >= COMN_EFL_SHUTDOWN_SECONDS)
{
errPrintf(WHERE, Module, -1,
MSG("Unable to stop efl checker.\n", 591));
break;
}
}
CANCEL_ALARM(eflCheckerControl.alarm);
}
}
/****************************************************************************
*
* This function is called by commandline. It resets volume's EFL tree.
*
****************************************************************************/
STATUS resetVolumeEFLTree(
GeneralMsg_s *genMsg,
unicode_t *volName)
{
Volume_s *volume = NULL;
STATUS status = zFAILURE;
Xaction_s *xaction;
struct purgeLogInfo_s
{
PurgeLogMsg_s purgeLogMsg;
LONG purgeLogLoc[MAX_PLOG_LOCATION_SIZE];
};
struct purgeLogInfo_s *purgeLogInfo = NULL;
/* find volume */
volume = COMN_VolumeNameLookup(genMsg, volName, FALSE, NULL);
if (volume == NULL)
{
goto exit;
}
if (COMN_LockVolumeActive(genMsg, volume, FALSE) != zOK)
{
goto exitRelease;
}
/* set up purge log */
purgeLogInfo = zalloc(sizeof(struct purgeLogInfo_s));
if (purgeLogInfo == NULL)
{
errPrintf(WHERE, Module, 706,
MSGNew("Error allocating memory for remove epoch operation\n", 0));
SetErrno(genMsg, zERR_NO_MEMORY);
goto exitUnlock;
}
SETUP_RESET_EFL_TREE_LOG(&purgeLogInfo->purgeLogMsg,
(void *)&purgeLogInfo->purgeLogLoc, volume);
xaction = volume->VOLcomnVolOps.VOL_beginXLocal(volume, X_CF_DEFAULT);
status = volume->VOLcomnVolOps.VOL_addPurgeLogEntry(
genMsg, volume, PLOG_EFL_RESET_TREE,
&purgeLogInfo->purgeLogMsg, (Xaction_s *)xaction);
volume->VOLcomnVolOps.VOL_endXLocal(xaction);
if (status != zOK)
{
goto exitUnlock;
}
/*
* Reset the EFL tree
*
*/
status = volume->VOLcomnVolOps.VOL_resetEFL(genMsg, volume);
if (status != zOK)
{
if (GetErrno(genMsg) == zERR_VOLUME_STATE_CHANGE_REQUESTED)
{
/* volume state changes, don't remove purge log */
goto exitUnlock;
}
}
xaction = volume->VOLcomnVolOps.VOL_beginXLocal(volume, X_CF_DEFAULT);
status = volume->VOLcomnVolOps.VOL_removePurgeLogEntry(
genMsg, volume, PLOG_EFL_RESET_TREE,
&purgeLogInfo->purgeLogMsg, (Xaction_s *)xaction);
volume->VOLcomnVolOps.VOL_endXLocal(xaction);
exitUnlock:
if (purgeLogInfo)
{
free(purgeLogInfo);
}
COMN_UnlockVolumeActive(volume, FALSE);
exitRelease:
COMN_Release(&volume);
exit:
return status;
}

View File

@@ -0,0 +1,295 @@
/****************************************************************************
|
| (C) Copyright 2003 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) module
|
|---------------------------------------------------------------------------
|
| $Author: vandana $
| $Date: 2005-08-10 01:03:51 +0530 (Wed, 10 Aug 2005) $
|
| $RCSfile$
| $Revision: 1177 $
|
|---------------------------------------------------------------------------
| This module is used to:
| NSSLOG routines that are aware of Common Layer specific structures.
+-------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <syslog.h>
#include "comnPublics.h"
#include "volume.h"
#include "nssLog.h"
/*
* NSSLOG_EventLogWithVolume() -
* Standard NSS Log routine that inserts the volume name into the message.
*
* Notes -
* Not part of NSS.NLM(nssLog.c), because volumes are common layer specific.
*
*/
STATUS NSSLOG_EventLogWithVolume(
Volume_s *volume,
#if zNETWARE
struct LoadDefinitionStructure *moduleHandle,
#endif
#if zLINUX
void *moduleHandle,
#endif
const char *where,
NINT logLevel,
NINT typeNumber, /* Type; see NSSLOG_TYPE_... defines */
char *message ) /* strlen message + strlen type must be less than 384 characters */
{
int addedOrError;
unicode_t *volumeName;
typedef struct Stack_s {
char log_information[400];
} Stack_s;
STACK_ALLOC();
if ( volume->v_volumeName )
{
volumeName = volume->v_volumeName;
}
else
{
volumeName = MSGNot(L"_NoName_");
}
addedOrError = LB_snprintf( aStack->log_information, sizeof( aStack->log_information ),
MSGNot("Volume \"%U\" - %s"),
volumeName, message );
if ( (addedOrError > 0) && (addedOrError < sizeof(aStack->log_information)) )
{ /* LB_snprintf succeeded - place into NSS.LOG */
(void)NSSLOG_EventLog( moduleHandle, WHERE, logLevel, typeNumber, aStack->log_information );
}
else
{ /* Buffer size error (or encoded error) */
STACK_FREE();
return( zERR_LOG_MESSAGE_TOO_BIG );
}
STACK_FREE();
return( zOK );
} /* End of NSSLOG_EventLogWithVolume() */
/*
* NSSLOG_EventLogWithVolumeAndGenMsg() -
* Standard NSS Log routine that inserts the volume name into the message.
*
* Notes -
* Not part of NSS.NLM(nssLog.c), because volumes are common layer specific.
*
*/
STATUS NSSLOG_EventLogWithVolumeAndGenMsg(
Volume_s *volume,
GeneralMsg_s *errorToReport,
#if zNETWARE
struct LoadDefinitionStructure *moduleHandle,
#endif
#if zLINUX
void *moduleHandle,
#endif
const char *where,
NINT logLevel,
NINT typeNumber, /* Type; see NSSLOG_TYPE_... defines */
char *message ) /* strlen message + strlen type must be less than 384 characters */
{
int addedOrError;
unicode_t *volumeName;
typedef struct Stack_s {
char log_information[400];
} Stack_s;
STACK_ALLOC();
if ( volume->v_volumeName )
{
volumeName = volume->v_volumeName;
}
else
{
volumeName = MSGNot(L"_NoName_");
}
addedOrError = LB_snprintf( aStack->log_information, sizeof( aStack->log_information ),
MSGNot("Volume \"%U\" Status %d(%s) - %s"),
volumeName,
GetErrno( errorToReport ), GetErrnoSetter( errorToReport ),
message );
if ( (addedOrError > 0) && (addedOrError < sizeof(aStack->log_information)) )
{ /* LB_snprintf succeeded - place into NSS.LOG */
(void)NSSLOG_EventLog( moduleHandle, WHERE, logLevel, typeNumber, aStack->log_information );
}
else
{ /* Buffer size error (or encoded error) */
STACK_FREE();
return( zERR_LOG_MESSAGE_TOO_BIG );
}
STACK_FREE();
return( zOK );
} /* End of NSSLOG_EventLogWithVolumeAndGenMsg() */
/*
* NSSLOG_EventLogWithPool() -
* Standard NSS Log routine that inserts the pool name into the message.
*
* Warnings -
* Caller must not own the Pool's beast latch.
*
* Notes -
* Not part of NSS.NLM(nssLog.c), because pools are common layer specific.
*
*/
STATUS NSSLOG_EventLogWithPool(
Pool_s *pool,
#if zNETWARE
struct LoadDefinitionStructure *moduleHandle,
#endif
#if zLINUX
void *moduleHandle,
#endif
const char *where,
NINT logLevel,
NINT typeNumber, /* Type; see NSSLOG_TYPE_... defines */
char *message ) /* strlen message + strlen type must be less than 384 characters */
{
GeneralMsg_s dummyGenMsg;
int addedOrError;
typedef struct Stack_s {
char log_information[400];
unicode_t poolName[zMAX_COMPONENT_NAME];
} Stack_s;
STACK_ALLOC();
COMN_SETUP_GENERAL_MSG_NO_CONNECTION_RESOLVE( &dummyGenMsg );
(void)COMN_GetPoolName( &dummyGenMsg, pool, aStack->poolName, NELEMS(aStack->poolName) );
addedOrError = LB_snprintf( aStack->log_information, sizeof( aStack->log_information ),
MSGNot("Pool \"%U\" - %s"),
aStack->poolName, message );
if ( (addedOrError > 0) && (addedOrError < sizeof(aStack->log_information)) )
{ /* LB_snprintf succeeded - place into NSS.LOG */
(void)NSSLOG_EventLog( moduleHandle, WHERE, logLevel, typeNumber, aStack->log_information );
}
else
{ /* Buffer size error (or encoded error) */
STACK_FREE();
return( zERR_LOG_MESSAGE_TOO_BIG );
}
STACK_FREE();
return( zOK );
} /* End of NSSLOG_EventLogWithPool() */
/*
* NSSLOG_EventLogWithPoolAndGenMsg() -
* Standard NSS Log routine that inserts the pool name into the message.
*
* Warnings -
* Caller must not own the Pool's beast latch.
*
* Notes -
* Not part of NSS.NLM(nssLog.c), because pools are common layer specific.
*
*/
STATUS NSSLOG_EventLogWithPoolAndGenMsg(
Pool_s *pool,
GeneralMsg_s *errorToReport,
#if zNETWARE
struct LoadDefinitionStructure *moduleHandle,
#endif
#if zLINUX
void *moduleHandle,
#endif
const char *where,
NINT logLevel,
NINT typeNumber, /* Type; see NSSLOG_TYPE_... defines */
char *message ) /* strlen message + strlen type must be less than 384 characters */
{
GeneralMsg_s dummyGenMsg;
int addedOrError;
typedef struct Stack_s {
char log_information[400];
unicode_t poolName[zMAX_COMPONENT_NAME];
} Stack_s;
STACK_ALLOC();
COMN_SETUP_GENERAL_MSG_NO_CONNECTION_RESOLVE( &dummyGenMsg );
(void)COMN_GetPoolName( &dummyGenMsg, pool, aStack->poolName, NELEMS(aStack->poolName) );
addedOrError = LB_snprintf( aStack->log_information, sizeof( aStack->log_information ),
MSGNot("Pool \"%U\" Status %d(%s) - %s"),
aStack->poolName,
GetErrno( errorToReport ), GetErrnoSetter( errorToReport ),
message );
if ( (addedOrError > 0) && (addedOrError < sizeof(aStack->log_information)) )
{ /* LB_snprintf succeeded - place into NSS.LOG */
(void)NSSLOG_EventLog( moduleHandle, WHERE, logLevel, typeNumber, aStack->log_information );
}
else
{ /* Buffer size error (or encoded error) */
STACK_FREE();
return( zERR_LOG_MESSAGE_TOO_BIG );
}
STACK_FREE();
return( zOK );
} /* End of NSSLOG_EventLogWithPoolAndGenMsg() */
/*
* NSSLOG_EventLog() -
* Log a message to C:NSS.LOG using syslog.nlm. Your message MUST
* be less than LB_VSN_PRINTF_LIMIT (including the NULL).
*
* Notes -
* The log is intended to be used by Novell to help track down
* NSS issues. Messages should not be languaged enabled.
* If you attempt to log more that 240 characters then your message
* will be truncated.
*
*/
#if zLINUX
STATUS NSSLOG_EventLog(
void *moduleHandle,
const char *where,
NINT logLevel,
NINT typeNumber, /* Type; see NSSLOG_TYPE_... defines */
char *message ) /* strlen message + strlen type must be less than 384 characters */
{
STATUS status;
status = NSSLOG_printf( moduleHandle, where, logLevel, typeNumber, "%s", message );
return( status );
} /* End of NSSLOG_EventLog() */
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,872 @@
/****************************************************************************
|
| (C) Copyright 1995-1997 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) module
|
|---------------------------------------------------------------------------
|
| $Author: blarsen $
| $Date: 2006-01-25 02:50:42 +0530 (Wed, 25 Jan 2006) $
|
| $RCSfile$
| $Revision: 1316 $
|
|---------------------------------------------------------------------------
| This module is used to:
| This looks up names
+-------------------------------------------------------------------------*/
#include <linux/module.h>
#include "comnPublics.h"
#include <xUnicode.h> /* NSS Library */
#include <xError.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "name.h"
#include "msgGen.h"
#include "msgName.h"
#include "comnBeasts.h"
#include "zParams.h"
#include "fullDirectoryInfo.h"
#include "nameSpace.h"
#include "comnBeastClass.h"
#include "pssStartup.h"
#include "nameScan.h"
#include "comnMacShortName.h"
/****************************************************************************
*
*****************************************************************************/
STATIC void NAME_HandleBeastlessName(
File_s *dir,
NameSpace_s *nameSpace,
NINT nameType,
unicode_t *name,
Zid_t badzid)
{
Zid_t curZid;
GeneralMsg_s genMsg;
// cnt NINT nameUniquifier;
typedef struct Stack_s {
FullDirectoryInfo_s dirInfo;
} Stack_s;
STACK_ALLOC();
ASSERT_MPKNSS_LOCK();
ASSERT_LATCH(&dir->FILEbeastLatch);
COMN_SETUP_GENERAL_MSG_NOSA(&genMsg);
/* try and look-up the entry again, but this time return the name. If we
* can't find it, something strange is going on, ignore it for now and
* move on. */
if ((curZid = dir->FILEcomnOps.BST_lookupByNameInDirectory(&genMsg,
&dir->FILEnamed,
nameSpace,nameType,name,/* cnt zFNU_UNDEFINED,
&nameUniquifier,*/&aStack->dirInfo)) == zINVALID_ZID)
{
STACK_FREE();
return;
}
/* verify that it is the same bad ZID. if not, then something is changing
* and ignore this and skip the entry */
if (curZid != badzid)
{
STACK_FREE();
return;
}
NAME_RemoveBeastlessNameFromDir(&genMsg,badzid,dir,nameSpace,
nameType,&aStack->dirInfo);
STACK_FREE();
}
/****************************************************************************
* Given the specific ASCII name information, this function checks the ASCII
* name cache to see if the name is in the cache. If it is not there, this
* function returns a NULL. If it is there, this function reads in the
* beast and returns a pointer to it.
*****************************************************************************/
void *NAME_FindNameInAsciiNameCache(
GeneralMsg_s *genMsg,
File_s *directory,
NameSpace_s *nameSpace,
NINT nameType,
NINT asciiNameLen,
char *asciiName,
NINT latchType,
BOOL dontDoVisibilityCheck
/* cnt, NINT *retNameUniquifier*/)
{
Zid_t zid;
NamedBeast_s *beast;
QUAD count;
BOOL negativeEntryFound;
ASSERT_LATCH(&directory->FILEbeastLatch);
//It is silly to try to lookup files if the parent is not a directory, but
//we should not assert here because the java stuff actually tries it. It
//just gets a "Not Found" error and keeps going happily on its way.
// zASSERT((directory->FILEattributes & zFA_SUBDIRECTORY) ||
// (nameType == zNTYPE_DATA_STREAM) ||
// (nameType == zNTYPE_EXTENDED_ATTRIBUTE));
if ((zid = NAME_GetNameFromCacheAscii(&directory->FILEvolume->VOLvolumeID,
directory->FILEzid, nameSpace, nameType, asciiNameLen, asciiName,
&negativeEntryFound, &count/* cnt, retNameUniquifier*/)) == zINVALID_ZID)
{ /* if not in the name cache or a negative entry */
if (negativeEntryFound)
{ /* there is no beast by this name */
SetErrno(genMsg, zERR_NAME_NOT_FOUND_IN_DIRECTORY);
return NULL;
}
/* no cache entry found */
return(NULL);
}
if ((beast = (NamedBeast_s *)COMN_LookupByZid(genMsg, directory->FILEvolume,
zid, latchType, dontDoVisibilityCheck)) == NULL)
{
if (GetErrno(genMsg) == zERR_ZID_NOT_FOUND)
{
/* Return as if the name was not found in the ASCII name cache.
* This will cause the name to be looked up in unicode. At that
* time, we can then properly call the NAME_HandleBeastlessName
* funciton to clean up the condition where we have a name that
* points to ZID that no longer exists
*/
ClearErrno(genMsg);
return(NULL);
}
return NULL;
}
return(beast);
}
/****************************************************************************
* HexRadix
* Before calling, you MUST make sure uniChr is an ASCII HEX digit
*****************************************************************************/
STATIC NINT HexRadix( unicode_t uniChr )
{
zASSERT( (uniChr < 128) && (LB_isxdigit(uniChr)) );
if (uniChr <= '9')
return(uniChr - '0');
if (uniChr <= 'Z')
return(0x0a + (uniChr - 'A'));
return(0x0a + (uniChr - 'a'));
}
/****************************************************************************
* This function is used to lookup specific names in a directory, in cases
* where the name should already exist. It does the following additional
* special checks:
* 1. If the name is not found and we just looked it up in the LONG
* namespace then try to look it up in the DOS name space.
* 2. If the name is still not found, check to see if it has any
* bracked special character syntax ... ie [xxxx], where there are
* exactly 4 hex digits surrounded by square brackets. If such
* syntax exists, convert each occurrence to a single unicode character
* and repeat the lookup steps.
* NOTE-NOTE-NOTE -- the caller is responsible to release the dosNameSpace
* pointer if it is filled in by this function.
*****************************************************************************/
void *NAME_FindNameInDirSpecialRules(
GeneralMsg_s *genMsg,
NamingMsg_s *nameMsg,
NameSpace_s **dosNameSpace,
BOOL negativeNameCacheFlag,
BOOL dontDoVisibilityCheck
/* cnt, NINT *retNameUniquifier*/)
{
ScanComponentMsg_s *scanMsg = &nameMsg->scanMsg;
NamedBeast_s *nextBeast = NULL;
BOOL convertedHexConstants = FALSE;
BOOL strippedFFChars = FALSE;
unicode_t *saveUniBuffer = NULL;
unicode_t *src;
unicode_t *dest;
LONG mangledZid;
NINT retLen;
typedef struct Stack_s {
unicode_t macName[zMAX_COMPONENT_NAME];
} Stack_s;
STACK_ALLOC();
tryLookupAgain:
nextBeast = NAME_FindNameInDir(genMsg, nameMsg->curFile,
nameMsg->workNameSpace, nameMsg->workNameType,
scanMsg->retUnicodeComp, scanMsg->retAsciiCompLen,
scanMsg->retAsciiComp, nameMsg->latchType,
negativeNameCacheFlag, dontDoVisibilityCheck
/* cnt, retNameUniquifier*/);
if (nextBeast != NULL)
{
/* Just in case genMsg has an error because of an invalid path,
* clear it because even though the path may have been invalid,
* we located it anyway */
if (GetErrno(genMsg) == zERR_INVALID_CHAR_IN_NAME)
{
ClearErrno(genMsg);
}
goto found;
}
/* We have some clients which get confused and mix LONG names with
* "DOS-8.3" names in the same path string. To get around this problem, if
* a name is not found in the long name space, we always double check the
* DOS name space to see if it exists there. */
if ((nameMsg->workNameSpaceID == zNSPACE_LONG) &&
(nameMsg->parseFlags & NAMPFL_tryDosIfLongFails))
{
if (*dosNameSpace == NULL)
{
*dosNameSpace = NSPACE_LOOKUP_NAMESPACE(genMsg, zNSPACE_DOS,
*dosNameSpace);
}
if (*dosNameSpace != NULL)
{
/* Reset the error and look for the name in the DOS name space */
ClearErrno(genMsg);
nextBeast = NAME_FindNameInDir(genMsg, nameMsg->curFile,
*dosNameSpace, nameMsg->workNameType,
scanMsg->retUnicodeComp, scanMsg->retAsciiCompLen,
scanMsg->retAsciiComp, nameMsg->latchType,
negativeNameCacheFlag, dontDoVisibilityCheck
/* cnt ,retNameUniquifier*/);
if (nextBeast != NULL)
{
/* Just in case genMsg has an error because of an invalid path,
* clear it because even though the path may have been invalid,
* we located it anyway */
if (GetErrno(genMsg) == zERR_INVALID_CHAR_IN_NAME)
{
ClearErrno(genMsg);
}
nameMsg->retParseFlags |= NAMRETPFL_foundDOSNameWithLong;
goto found;
}
}
}
/* Right here we do some extra work to allow for the user to type in a
* single unmappable unicode character in the form of a 6 character hex
* sequence of "[xxxx]", where "[xxxx]" is mapped to a single unicode
* character. We used to do this special character mapping in the
* AsciiToUnicode converter, but we discovered that some complications
* arose from that approach. Doing the mapping here allows for real file
* names to exist with the [xxxx] syntax as 6 actual file name characters
* rather than as a single char. */
if ((!convertedHexConstants) &&
(GetErrno(genMsg) == zERR_NAME_NOT_FOUND_IN_DIRECTORY) &&
((src = unichr(scanMsg->retUnicodeComp,L'[')) != NULL))
{
/* We didn't find the name in the directory, and the name contains a
* '[' character. Start processing at the first '[' character. */
dest = src;
while (*src != 0)
{
if ((src[0] == L'[') && (src[5] == L']') &&
(src[1]<128) && (LB_isxdigit(src[1])) &&
(src[2]<128) && (LB_isxdigit(src[2])) &&
(src[3]<128) && (LB_isxdigit(src[3])) &&
(src[4]<128) && (LB_isxdigit(src[4])))
{
if (!convertedHexConstants)
{
saveUniBuffer = malloc(zMAX_COMPONENT_NAME * 2);
if (saveUniBuffer != NULL)
{
unicpy( saveUniBuffer, scanMsg->retUnicodeComp );
}
}
/* This is a brute force conversion from 4 digit hex to unicode */
*dest++ = ((HexRadix(src[1]) << 12) +
(HexRadix(src[2]) << 8) +
(HexRadix(src[3]) << 4) +
(HexRadix(src[4]) ));
src += 6;
convertedHexConstants = TRUE;
}
else /* not 4digit hex, skip to next char */
{
*dest++ = *src++;
}
}
*dest++ = *src++; /* Copy final NULL */
if (convertedHexConstants)
{
/* IMPORTANT-IMPORTANT-IMPORTANT
* We must never add positive name cache entries where the unicode
* name has been converted, BUT the ascii name has not. It is much
* easier to just blow the unconverted ASCII name away here and
* this eliminates the problem. */
scanMsg->retAsciiCompLen = 0;
scanMsg->retAsciiComp = NULL;
ClearErrno(genMsg);
goto tryLookupAgain;
}
}
/*
* If the NAME is a DOS name and it has extended ASCII characters in it,
* re-parse the ASCII component using original DOS rules and try to look
* it up again.
*/
if ((nameMsg->workNameSpaceID == zNSPACE_DOS) &&
(scanMsg->retScanFlags & NSRETSFL_hasExtendedASCII))
{
/* Note - only DOS sets this flag. We did not find the name, but the
* name contains extended ASCII characters. Reparse the path component
* using traditional NetWare uppercasing/legal character rules and then
* try to look it up one more time.
*/
if (NMSG_ReparseNameMsgDOSComponent(genMsg,nameMsg) == zOK)
{
COMN_SET_NAMING_MSG_CONTINUE_AFTER_ILLEGAL_CHARS(nameMsg);
ClearErrno(genMsg);
goto tryLookupAgain;
}
}
/*
* If the NAME is a LONG name and it has at least one FF character,
* then strip extra FF characters and try it again one more time.
*/
if ((!strippedFFChars) &&
(nameMsg->workNameSpaceID == zNSPACE_LONG) &&
((src = unichr(scanMsg->retUnicodeComp,NSSUnicodeFF)) != NULL))
{
/* We didn't find the name in the directory, and the name contains at
* least one "FF" character. Start processing at the first "FF"
* character and strip pairs of "FF FF" chars to single "FF" chars.
*/
dest = src;
while (*src != 0)
{
if ((src[0] == NSSUnicodeFF) && (src[1] == NSSUnicodeFF))
{
if ((!strippedFFChars) && (saveUniBuffer == NULL))
{
saveUniBuffer = malloc(zMAX_COMPONENT_NAME * 2);
if (saveUniBuffer != NULL)
{
unicpy( saveUniBuffer, scanMsg->retUnicodeComp );
}
}
*dest++ = NSSUnicodeFF;
src += 2;
strippedFFChars = TRUE;
}
else /* not "FF FF", skip to next char */
{
*dest++ = *src++;
}
}
*dest++ = *src++; /* Copy final NULL */
if (strippedFFChars)
{
/* IMPORTANT-IMPORTANT-IMPORTANT
* We must never add positive name cache entries where the unicode
* name has been converted, BUT the ascii name has not. It is much
* easier to just blow the unconverted ASCII name away here and
* this eliminates the problem. */
scanMsg->retAsciiCompLen = 0;
scanMsg->retAsciiComp = NULL;
ClearErrno(genMsg);
goto tryLookupAgain;
}
}
if (nameMsg->workNameSpaceID == zNSPACE_MAC)
{
// clear any previous error
ClearErrno(genMsg);
mangledZid = COMN_GetZidFromMangledName(scanMsg->retUnicodeComp);
if (mangledZid < zFIRST_ALLOCATABLE_ZID)
{
// zid is not valid, can't be embedded zid
SetErrno(genMsg, zERR_NAME_NOT_FOUND_IN_DIRECTORY);
goto error;
}
// do comn_lookupbyzid and return beast ptr
nextBeast = COMN_LookupByZid (genMsg, nameMsg->curvol,
(Zid_t) mangledZid, nameMsg->latchType, FALSE);
ClearErrno(genMsg); // we may have to set it later
if (nextBeast == NULL)
{
// lookup by zid failed, report not found
SetErrno(genMsg, zERR_NAME_NOT_FOUND_IN_DIRECTORY);
goto error;
}
// verify beast is right type
if ((!COMN_IsDerivedFrom(nextBeast, zFTYPE_NAMED_DATA_STREAM))
|| (nextBeast->NAMEDfirstParentNameType != nameMsg->workNameType))
{
// no match, reject it
SetErrno(genMsg, zERR_NAME_NOT_FOUND_IN_DIRECTORY);
goto error;
}
// does name match mangled name?
if (COMN_GetNameFromBeast(genMsg, nextBeast, /* cnt zFNU_FIRST_PARENT,*/
zNSPACE_MAC,
zMAX_COMPONENT_NAME,
aStack->macName, &retLen) != zOK)
{
goto error;
}
if (!COMN_VerifyMangledMacName (scanMsg->retUnicodeComp,
aStack->macName) )
{
// we found a zid, but it doesn't match reject it
SetErrno(genMsg, zERR_NAME_NOT_FOUND_IN_DIRECTORY);
goto error;
}
// cnt *retNameUniquifier = zFNU_FIRST_PARENT;
goto found;
}
error:
if (nextBeast)
{
COMN_UnlatchAndRelease( &nextBeast, nameMsg->latchType);
}
if (saveUniBuffer)
{
/* We converted the string and didn't find the name, put the original
* name back */
unicpy(scanMsg->retUnicodeComp, saveUniBuffer);
free(saveUniBuffer);
}
STACK_FREE();
return(NULL);
found:
if (saveUniBuffer)
{
free(saveUniBuffer);
}
STACK_FREE();
return(nextBeast);
}
/****************************************************************************
* Given the specific unicode name information, this will look in the name
* cache for the unicode name. If it doesn't find the name in the name cache
* it calls the BST_lookupByNameInDIrectory to ask the LSS to search the
* directory. If
* the name is found and it is not already in the name cache, it's unicode
* and ascii equivalents are added to the name cache.
*****************************************************************************/
Zid_t NAME_FindZidForNameInDir(
GeneralMsg_s *genMsg,
void *_directory,
NameSpace_s *nameSpace,
NINT nameType,
unicode_t *uniName,
NINT asciiNameLen,
char *asciiName,
BOOL negativeNameCacheFlag /* INPUT: do we add negative entries to the cache? */
/* cnt, NINT *retNameUniquifier*/)
{
File_s *directory = _directory;
Zid_t zid;
QUAD count;
BOOL negativeEntryFound;
ASSERT_MPKNSS_LOCK();
ASSERT_LATCH(&directory->FILEbeastLatch);
zASSERT((directory->FILEattributes & zFA_SUBDIRECTORY) ||
(nameType == zNTYPE_DATA_STREAM) ||
(nameType == zNTYPE_EXTENDED_ATTRIBUTE));
if ((zid = NAME_GetNameFromCacheUnicode(&directory->FILEvolume->VOLvolumeID,
directory->FILEzid, nameSpace, nameType, uniName, &negativeEntryFound,
&count/* cnt, retNameUniquifier*/)) == zINVALID_ZID)
{ /* if not in the name cache or a negative entry */
if (negativeEntryFound)
{ /* there is no beast by this name */
SetErrno(genMsg, zERR_NAME_NOT_FOUND_IN_DIRECTORY);
goto errorExit;
}
/* no cache entry found */
if ((zid = directory->FILEcomnOps.
BST_lookupByNameInDirectory(genMsg, &directory->FILEnamed, nameSpace, nameType,
uniName, /* cnt zFNU_UNDEFINED, retNameUniquifier,*/
NULL)) == zINVALID_ZID)
{ /* the beast was not found */
if (negativeNameCacheFlag)
{ /* add a negative cache entry if allowed */
unicode_t *src;
BOOL skipNegativeAdd = FALSE;
/* IMPORTANT-IMPORTANT-IMPORTANT
* We must never add a negative name cache entry that has
* [xxxx] syntax in it (see COMN_Lookup where it converts
* this syntax to a single unicode character). If we were
* to add such a string, it can really confuse the whole
* system. */
src = uniName;
while ((src = unichr(src,L'[')) != NULL)
{
/* Found another starting '[' ... check it out */
if ((src[0] == L'[') && (src[5] == L']') &&
(src[1]<128) && (LB_isxdigit(src[1])) &&
(src[2]<128) && (LB_isxdigit(src[2])) &&
(src[3]<128) && (LB_isxdigit(src[3])) &&
(src[4]<128) && (LB_isxdigit(src[4])))
{
skipNegativeAdd = TRUE;
break;
}
++src;
}
if (!skipNegativeAdd)
{
NAME_AddNameToCache(count, directory->FILEvolume,
directory->FILEzid, nameSpace, nameType, uniName,
asciiNameLen, asciiName, zINVALID_ZID
/* cnt,zFNU_INVALID_NAME_UNIQUIFIER*/);
}
}
goto errorExit;
}
/* the beast was found */
NAME_AddNameToCache(count, directory->FILEvolume,
directory->FILEzid, nameSpace, nameType, uniName,
asciiNameLen, asciiName, zid/* cnt, *retNameUniquifier*/);
}
if ( GetErrno( genMsg ) == zERR_ZID_NOT_FOUND )
{ /* By only clearing errno when zERR_ZID_NOT_FOUND
* we do not mess with wierd code that looks
* at errnos on NON-errors. Some of our callers
* only clearerrno if zERR_INVALID_CHAR_IN_NAME is
* set which worries me I.E. why not clear all
* the time if NO ONE is looking at it?
*/
ClearErrno( genMsg );
}
errorExit:
return zid;
}
/****************************************************************************
* Given the specific unicode name information, this will look in the name
* cache for the unicode name. If it doesn't find the name in the name cache
* it calls the BST_lookupByNameInDIrectory to ask the LSS to search the
* directory. If the name is found, the beast is read into memory. If
* the name is found and it is not already in the name cache, it's unicode
* and ascii equivalents are added to the name cache.
*****************************************************************************/
void *NAME_FindNameInDir(
GeneralMsg_s *genMsg,
void *_directory,
NameSpace_s *nameSpace,
NINT nameType,
unicode_t *uniName,
NINT asciiNameLen,
char *asciiName,
NINT latchType,
BOOL negativeNameCacheFlag, /* INPUT: do we add negative entries to the cache? */
BOOL dontDoVisibilityCheck
/* cnt NINT *retNameUniquifier*/)
{
File_s *directory = _directory;
Zid_t zid;
NamedBeast_s *beast;
ASSERT_MPKNSS_LOCK();
ASSERT_LATCH(&directory->FILEbeastLatch);
zASSERT((directory->FILEattributes & zFA_SUBDIRECTORY) ||
(nameType == zNTYPE_DATA_STREAM) ||
(nameType == zNTYPE_EXTENDED_ATTRIBUTE));
if ((zid = NAME_FindZidForNameInDir(genMsg, _directory, nameSpace, nameType,
uniName, asciiNameLen, asciiName,
negativeNameCacheFlag
/* cnt, retNameUniquifier*/)) == zINVALID_ZID)
{
goto errorExit;
}
if ((beast = (NamedBeast_s *)COMN_LookupByZid(genMsg, directory->FILEvolume,
zid, latchType, dontDoVisibilityCheck)) == NULL)
{
if (GetErrno(genMsg) == zERR_ZID_NOT_FOUND)
{
NAME_HandleBeastlessName(directory,nameSpace,nameType,uniName,zid);
ForceSetErrno(genMsg,zERR_NAME_NOT_FOUND_IN_DIRECTORY);
}
goto errorExit;
}
return(beast);
errorExit:
return NULL;
}
/**************************************************************************
* We have found a name in the directory and we could not find the
* associated beast for it. This is going to report an error and then
* delete the name.
***************************************************************************/
STATUS NAME_RemoveBeastlessNameFromDir(
GeneralMsg_s *genMsg,
Zid_t badzid,
void *_curdir,
NameSpace_s *nameSpace,
NINT nameType,
FullDirectoryInfo_s *nameInfo)
{
#if (zGET_NAME_VARIABLE_DATA_SIZE < (zMAX_FULL_NAME*2))
#error The zGET_NAME_VARIABLE_DATA_SIZE must be >= (zMAX_FULL_NAME * 2),
#error because we use it to get a full unicode path
#endif
NamedBeast_s *curdir = _curdir;
GetNameMsg_s gfnMsg;
unicode_t *fullName;
zGetName_s *fullNameBuf = NULL;
Xaction_s *xaction;
NINT latchType;
STATUS status;
NameSpace_s *pathNameSpace;
NINT pathNameType;
typedef struct Stack_s {
NamingMsg_s noCleanupNameMsg;
} Stack_s;
STACK_ALLOC();
ASSERT_MPKNSS_LOCK();
ASSERT_LATCH(&curdir->NAMEDbeastLatch); /* make sure directory is latched */
COMN_INIT_NAMING_MSG(&aStack->noCleanupNameMsg);
/*---------------------------------------------------------------------------
* Try and get the full name of the file. We do thing by getting the name
* of the DIR and the appending the filename to it. If we have a problem
* getting the full name, just give the file name.
*---------------------------------------------------------------------------*/
/* get a buffer to return the full name into*/
if ((fullNameBuf = COMN_GetPathNameWorkBuffer(genMsg)) == NULL)
{
fullName = nameInfo->name;
latchType = GET_LATCH_TYPE(&curdir->NAMEDbeastLatch);
}
else
{
/*---------------------------------------------------------------------------
* Setup a nameMessage with all of the necessary beast/volume/nameSpace
* pointers --- BUT --- DO NOT do the extra use counts and latching normally
* required by a nameMsg. WE WILL NOT CLEANUP THE NAMEMSG. All of
* the pointers are already either inUse, latched or both. This is simply
* a method of setting up a temporary nameMsg to be used by COMN_GetName.
* All pointers are inuse/latched and cleaned up by the caller of this function.
*---------------------------------------------------------------------------*/
/* Note, if the nameType/nameSpace is DataStream or Extended Attribute
* then we switch to the long name space to get the parent file's
* name. We cannot use these namespaces to get the whole path */
if ((nameSpace->nSpaceID == zNSPACE_DATA_STREAM) ||
(nameSpace->nSpaceID == zNSPACE_EXTENDED_ATTRIBUTE) ||
(nameType == zNTYPE_DATA_STREAM) ||
(nameType == zNTYPE_EXTENDED_ATTRIBUTE))
{
pathNameType = zNTYPE_FILE;
pathNameSpace = COMN_NameSpaceIDLookup(genMsg, zNSPACE_LONG);
}
else
{
pathNameType = nameType;
pathNameSpace = nameSpace;
COMN_USE_BEAST(&pathNameSpace->NSPACEroot);
}
latchType = GET_LATCH_TYPE(&curdir->NAMEDbeastLatch);
COMN_SETUP_NAMING_MSG_FILE_BEAST_PTR(&aStack->noCleanupNameMsg,
curdir->NAMEDvolume,
curdir->NAMEDfirstParentZid,
// cnt curdir->NAMEDfirstParentNameUniquifier,
(File_s *)curdir,
NAMPMODE_FullyResolveDirectory,
latchType,
pathNameSpace,
pathNameType,
NULL);
/* get the full path name of the parent directory */
COMN_STRUCT_INIT(gfnMsg);
COMN_SETUP_GET_NAME_MSG(&gfnMsg,
zGFN_INCLUDE_PATH|zGFN_INCLUDE_VOLUME,
GFN_NO_SEPARATOR_AFTER_VOLUME_COLON,
zPFMT_UNICODE, pathNameSpace->nSpaceID,
fullNameBuf, UNI_PATHWORKBUF_SIZE);
if (COMN_GetName(genMsg,&aStack->noCleanupNameMsg,&gfnMsg) != zOK)
{
/* if we couldn't get it the full name, release the buffer */
COMN_ReleasePathNameWorkBuffer(&fullNameBuf);
fullName = nameInfo->name;
/* Some errors from COMN_GetName have released the latch. If this
* is the case, we must re-latch it */
if (aStack->noCleanupNameMsg.latchType == NOTLATCHED)
{
switch(latchType)
{
case XLATCHED:
X_LATCH(&curdir->NAMEDbeastLatch);
break;
case SLATCHED:
S_LATCH(&curdir->NAMEDbeastLatch);
break;
}
}
else
{
zASSERT(aStack->noCleanupNameMsg.latchType == latchType);
}
}
else
{
NINT len;
NINT separatorLen;
unicode_t *separatorStr;
if (pathNameSpace->nSpaceOps->getSeparator(genMsg,PATH_SEPARATOR,
&separatorStr, &separatorLen) != zOK)
{
zASSERT("Unable to get path sepatator, This should not happen\n" == NULL);
separatorLen = 1;
separatorStr = MSGNot(L"\\");
}
/* we have the directory name, add in the file name */
fullName = fullNameBuf->name;
len = unilen(fullName);
if (len < UNI_PATHWORKBUF_SIZE-separatorLen)
{
unicpy(&fullName[len],separatorStr);
len += separatorLen;
}
unimcpy(&fullName[len],nameInfo->name,UNI_PATHWORKBUF_SIZE-len);
}
COMN_Release(&pathNameSpace);
}
/*---------------------------------------------------------------------------
* Delete the spurious name. The directory that comes in is ALWAYS SLatched
* so we must upgrade the latch and then downgrade it after.
*---------------------------------------------------------------------------*/
switch(latchType)
{
case XLATCHED:
break;
case SLATCHED:
UP_LATCH(&curdir->NAMEDbeastLatch);
break;
default:
zASSERT("Unknown latch type\n" == NULL);
break;
}
xaction = COMN_BeginXLocal(curdir);
NAME_RemoveNameFromCache(genMsg, curdir->NAMEDvolume,
curdir->NAMEDzid, nameInfo->nameSpaceMask, nameType, nameInfo->name,
0);
/* Call this again with "NAMEForcedUpper" to make sure we get a unix
* name cache entry.
*/
NAME_RemoveNameFromCache(genMsg, curdir->NAMEDvolume,
curdir->NAMEDzid, nameInfo->nameSpaceMask, nameType, nameInfo->name,
NAMEforcedUpper);
status = curdir->NAMEDcomnOps.BST_removeNameFromDirectory(genMsg,
badzid, curdir,nameInfo->nameSpaceMask,
nameType,nameInfo->name,/* cnt zFNU_UNDEFINED,*/NF_UPDATE_NAME,
xaction,NULL);
/* report the error message */
if (status == zOK)
{
#if NSS_DEBUG IS_ENABLED
errPrintf(WHERE, Module, 624,
MSG("File object %d, whose name is \"%U\", could not be found.\n"
"The name has been removed! Couldn't find Beast. Run Verify.", 800),
(NINT)nameInfo->zid, fullName);
#endif
}
else
{
errPrintf(WHERE, Module, 625,
MSG("File object %d, whose name is \"%U\", "
"could not be found. The system was unable to "
"remove the name (status=%d)!\n", 801), /* Purposeful extra \n */
(NINT)nameInfo->zid, fullName, GetErrno(genMsg));
zASSERT("This is a nameTree corruption problem" == 0);
}
COMN_EndXLocal(curdir,&xaction);
switch(latchType)
{
case XLATCHED:
break;
case SLATCHED:
DOWN_LATCH(&curdir->NAMEDbeastLatch);
break;
default:
zASSERT("Unknown latch type\n" == NULL);
break;
}
if (fullNameBuf)
COMN_ReleasePathNameWorkBuffer(&fullNameBuf);
STACK_FREE();
return GetErrno(genMsg);
}

View File

@@ -0,0 +1,5 @@
/****************************************************************************
| MARS-NWE libnwnss import wrapper for NSS shared NDP idbroker source.
+-------------------------------------------------------------------------*/
#include <sharedsrc/ndp_idbroker.c.h>

View File

@@ -0,0 +1,66 @@
/****************************************************************************
| Userspace sysimp boundary for libnwnss.
|
| public_core/sharedsrc/sysimp.c.h is the real NSS sysimp implementation, but
| its Linux userspace branch depends on DDS/NDPS headers and runtime entry
| points that are outside the NSS userspace core import. Keep the exported
| sysimp state visible and inactive here until the eDirectory/DDS provider is
| deliberately wired in.
+-------------------------------------------------------------------------*/
#include <stddef.h>
#include <library/omni.h>
#include <public/zError.h>
BOOL NdsPublicsLoaded = FALSE;
LONG NdsPublicsHandle = 0;
int (*NDSRenameEventFunc)() = NULL;
int (*NDSDeleteEventFunc)() = NULL;
LONG NDSEventHandlerHandle = 0;
BOOL NDSEventRegistered = FALSE;
int (*DDSGetLocalAgentInfoPtr)() = NULL;
int (*DDSGetLocalEntryNamePtr)() = NULL;
int (*DDCCreateContextPtr)() = NULL;
int (*DDCDuplicateContextPtr)() = NULL;
int (*DDCResolveNamePtr)() = NULL;
int (*DDCGetEntryInfoPtr)() = NULL;
void (*DDCFreeContextPtr)() = NULL;
int (*DDCSetContextFlagsPtr)() = NULL;
int (*DDCSetContextEntryIDPtr)() = NULL;
int (*DDCLoginPtr)() = NULL;
int (*DDSLoginAsServerPtr)() = NULL;
int (*DDCCreateEntryPtr)() = NULL;
int (*DDCRemoveEntryPtr)() = NULL;
int (*DDCRemoveAttributePtr)() = NULL;
int (*DDCGenerateKeyPairPtr)() = NULL;
int (*DDCLogoutPtr)() = NULL;
int (*DDCReadToBufferPtr)() = NULL;
int (*DDCReadToCBPtr)() = NULL;
int (*DDCListToBufferPtr)() = NULL;
int (*DDCModifyEntryPtr)() = NULL;
int (*DDCModifyRDNPtr)() = NULL;
int (*DDCGetServerNamePtr)() = NULL;
int (*DDCSetContextBaseDNPtr)() = NULL;
int (*DDCAuthenticateConnectionPtr)() = NULL;
int (*DDCGetEffectivePrivilegesPtr)() = NULL;
int (*DDCCheckConsoleOperatorPtr)() = NULL;
int (*DDCNameToIDPtr)() = NULL;
int (*DDCConnectToReferralPtr)() = NULL;
int (*DDCGetDefaultAddressPtr)() = NULL;
int (*DDCConnectToAddressPtr)() = NULL;
UINT32 (*DDCContextEntryIDPtr)() = NULL;
int (*DDCPingPtr)() = NULL;
STATUS LB_ImportNDSPublics(LONG handle)
{
(void)handle;
NdsPublicsLoaded = FALSE;
return zFAILURE;
}
void LB_UnimportNDSPublics(LONG handle)
{
(void)handle;
NdsPublicsLoaded = FALSE;
}

View File

@@ -0,0 +1,201 @@
/****************************************************************************
|
| (C) Copyright 1985, 1991, 1993, 1996-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 Advance File Services (NSS) module
|
|---------------------------------------------------------------------------
|
| $Author: vandana $
| $Date: 2005-08-10 01:03:51 +0530 (Wed, 10 Aug 2005) $
|
| $RCSfile$
| $Revision: 1177 $
|
|---------------------------------------------------------------------------
| This module is used to:
| Manage VOLUME code
+-------------------------------------------------------------------------*/
#include <linux/module.h>
#include "comnPublics.h"
#include <que.h>
#include <stdio.h>
#include <stdlib.h>
#include <xError.h>
#include "volume.h"
#include "pssStartup.h"
#include "adminVolume.h"
SEThead_t NSSMasterVolumeList = SET_STATIC_INIT(NSSMasterVolumeList);
SEThead_t NSSMasterPoolList = SET_STATIC_INIT(NSSMasterPoolList);
/**************************************************************************
* This initializes the VOLUME system
*
***************************************************************************/
STATUS VOLUME_Startup(
GeneralMsg_s *genMsg)
{
return zOK;
}
/**************************************************************************
* This is called when
* 1) Someone downs the server (CMN_ServerDown()).
* 2) The NSS.NLM is exiting (CMN_GlobalShutdown() which is called
* by GenericExitRoutine() of NSS.NLM).
*
* In the first case, the NWSA (FixFixFix6 - put into COMN LYR) has the DOWN
* event hooked and prompts user if files are open on MOUNTed volumes. By
* the time this routine is called we are at a point where we have to
* deactivate even if files are open.
* In the 2nd case all non ADMIN volume's are already deactivated.
*
***************************************************************************/
STATUS applyVolumeShutdown (SETlink_t *item, void *verbose)
{
Volume_s *volume = STRUCT(item, Volume_s, masterVolLink);
GeneralMsg_s genMsg;
STATUS status;
NINT errorcode;
NINT mode = (verbose ? VOLMODE_VERBOSE : 0);
typedef struct Stack_s {
unicode_t vName[zMAX_COMPONENT_NAME];
} Stack_s;
STACK_ALLOC();
ASSERT_MPKNSS_LOCK();
COMN_SETUP_GENERAL_MSG_NOSA(&genMsg);
/*
* We do not do internal volumes as the LSS is
* responsible for this.
*
* We skip the admin volume because it must be last and
* therefore we let ADMINVOL_Shutdown() do when
* BEAST_Shutdown() calls it from CMN_GlobalShutdown().
* If we call here then admin volume rejects the
* state change, but we display that we are deactivating
* the volume. Therefore, when we really deactivate we
* display a SECOND deactivate message.
*/
if ( !VOL_ACCESSIBLE1(volume) || (volume == COMN_GetAdminVolume()))
{
STACK_FREE();
return zOK;
}
COMN_GetVolumeName(&genMsg,volume,aStack->vName,NELEMS(aStack->vName));
status = COMN_ChangeVolumeState( &genMsg, volume, zVOLSTATE_UNKNOWN, mode);
if (status != zOK)
{
/*- check if admin volume -*/
errorcode = GetErrno( &genMsg);
errPrintf(WHERE, Module, 635,
MSG("Could not deactivate Volume %U, status=%d.", 196),
aStack->vName, errorcode);
zASSERT("Error deactivating volume" == 0);
}
STACK_FREE();
return zOK;
}
void VOLUME_Shutdown(
BOOL verbose)
{
SET_APPLY( &NSSMasterVolumeList, applyVolumeShutdown, (void *)verbose);
}
/**************************************************************************
* This initializes the POOL system
*
***************************************************************************/
STATUS POOL_Startup(
GeneralMsg_s *genMsg)
{
return zOK;
} /* End of POOL_Startup() */
/**************************************************************************
* This is called when
* 1) Someone downs the server (CMN_ServerDown()).
* 2) The NSS.NLM is exiting (CMN_GlobalShutdown() which is called
* by GenericExitRoutine() of NSS.NLM).
*
* In the first case, the NWSA (FixFixFix6 - put into COMN LYR) has the DOWN
* event hooked and prompts user if files are open on MOUNTed volumes. By
* the time this routine is called we are at a point where we have to
* deactivate even if files are open.
* In the 2nd case all non ADMIN volume's are already deactivated.
*
***************************************************************************/
void POOL_Shutdown(
BOOL verbose)
{
STATUS status;
NINT mode = (verbose ? VOLMODE_VERBOSE : 0);
Pool_s *pool;
GeneralMsg_s genMsg;
typedef struct Stack_s {
unicode_t poolName[zMAX_COMPONENT_NAME];
} Stack_s;
STACK_ALLOC();
ASSERT_MPKNSS_LOCK();
COMN_SETUP_GENERAL_MSG_NOSA(&genMsg);
SET_FOREACHBLOCKING(&NSSMasterPoolList, pool, Pool_s, masterPoolLink)
{ /*** You MUST NOT use continue in this loop because the macro
*** SET_FOREACHBLOCKINGEND (at end of for loop) must be called
*** every time through the loop. Technically, you
*** can use a continue BEFORE any blocking calls.
***/
COMN_USE_BEAST( &pool->POOLroot );
COMN_GetPoolName( &genMsg, pool, aStack->poolName, NELEMS(aStack->poolName) );
status = COMN_ChangePoolState( &genMsg, pool, zVOLSTATE_UNKNOWN, mode);
if (status != zOK)
{
errPrintf(WHERE, Module, -1,
MSG("Could not deactivate Pool %U, status=%d.", 176),
aStack->poolName, GetErrno(&genMsg));
zASSERT("Error deactivating pool" == NULL);
}
COMN_Release( &pool );
SET_FOREACHBLOCKINGEND(&NSSMasterPoolList, pool, Pool_s, masterPoolLink)
}
STACK_FREE();
} /* End of POOL_Shutdown() */

View File

@@ -1,3 +1,4 @@
#include <stddef.h>
/****************************************************************************
* COMN module identity for userspace libnwnss.
*
@@ -6,3 +7,10 @@
* the identity local and explicit instead of leaving it in the temporary bridge.
****************************************************************************/
const char Module[] = "libnwnss";
/* Userspace libnwnss has no NetWare/Linux kernel module handle. Imported
* COMN sources pass this value through OS-service macros that are guarded in
* nwnssSourceCompat.h/nssOSAPIs.h.
*/
struct LoadDefinitionStructure;
struct LoadDefinitionStructure *CMN_ModuleHandle = NULL;

View File

@@ -0,0 +1,593 @@
/****************************************************************************
|
| (C) Copyright 1985, 1991, 1993, 1996-1999 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
|
|***************************************************************************
|
| NSS Compression Management module
|
|---------------------------------------------------------------------------
|
| $Author: ying $
| $Date: 2005-05-11 23:59:19 +0530 (Wed, 11 May 2005) $
|
| $RCSfile$
| $Revision: 976 $
|
|---------------------------------------------------------------------------
| Module Description:
|
+-------------------------------------------------------------------------*/
#include <pssDebug.h>
#include "cmDefs.h"
#include "cmRuntime.h"
#include "cmAlgoMan.h"
#include "comnCompress.h"
#include "cmActivity.h"
#include "cmNSS.h"
#include "cmCompFile.h"
#include "cmControl.h"
/*
* Called to indicate successful completion of a (de)compression activity.
*/
STATIC QUAD totalCompActivities = 0;
STATIC void CM_activityDone(CMActivity_s *activity)
{
RootBeast_s *uncompBeast = activity->decompStream.beast;
RootBeast_s *compBeast = activity->compStream.beast;
CompressInfo_s *compInfo = BEAST_CM_INFO(uncompBeast);
GeneralMsg_s genMsg;
QUAD offset = activity->decompStream.beastOffset;
NINT newCompState;
NINT num;
Xaction_s *localXaction = NULL;
ASSERT_MPKNSS_LOCK();
XLATCH_BEAST(uncompBeast);
XLATCH_BEAST(compBeast);
COMN_SETUP_GENERAL_MSG_NOSA(&genMsg);
activity->state = CM_ACTIVITY_STATE_FINISHED;
if (activity->op == CM_ACTIVITY_OP_COMPRESS)
{
newCompState = COMP_STATUS_COMPRESSED;
if (activity->keepSrcChunk)
newCompState |= COMP_STATUS_UNCOMPRESSED;
if (compInfo->p.chunkSize > 0)
{
Buffer_s *cmbuf;
QUAD compChunkOffset;
CompChunkHdr_s *chunkHdr;
if (getCompChunkOffset(&genMsg, compBeast, offset,
compInfo->p.chunkSize, &compChunkOffset) != zOK)
goto cleanupAndExit;
/* Set compressed chunk size in chunk header */
cmbuf = CM_fetchFileBlk(&genMsg, compBeast,
compChunkOffset >> compBeast->blkSizeShift,
CACHE_UPDATE, 0);
if (! cmbuf)
goto cleanupAndExit;
mapBufferPage(cmbuf);
chunkHdr = (CompChunkHdr_s *)
(cmbuf->pBuf.data + (compChunkOffset &
((1 << compBeast->blkSizeShift) - 1)));
chunkHdr->compChunkSize = activity->compStream.beastSize;
unmapBufferPage(cmbuf);
CACHE_DIRTY_RELEASE(cmbuf);
(void) setCompChunkValidRange(&genMsg,
activity->compStream.beast, offset,
compInfo->p.chunkSize,
activity->compStream.beastOffset,
activity->compStream.beastSize);
(void) setChunkCompStatus(&genMsg, activity->compStream.beast,
offset, compInfo->p.chunkSize, newCompState);
UNXLATCH_BEAST(compBeast);
BST_flush(compBeast);
XLATCH_BEAST(compBeast);
if (! activity->keepSrcChunk)
{
/*
* create a hole in the uncompBeast in the range
* <decompStream.beastOffset, decompStream.beastSize>
* This step may not be possible with current NSS
* implementation. In case of whole file compression, truncate
* the beast.
* ??? to be filled in when fully supporting chunky compression.
*/
}
}
else
{
/* Set Compressed beast's new (logical) EOF, and flush compBeast */
SET_DATASTREAM_SIZE(&genMsg, compBeast,
activity->compStream.beastOffset +
activity->compStream.beastSize);
COMN_MARK_BEAST_DIRTY(compBeast);
UNXLATCH_BEAST(compBeast);
BST_flush(compBeast);
XLATCH_BEAST(compBeast);
#if 0
if (! activity->keepSrcChunk)
{
/* Discard uncompressed data */
/*
* XXX Shouldn't call BST_truncate to truncate the uncompBeast.
* BST_truncate in turn performs compression-related processing,
* which involves throwing away the compressed stream too.
* We should instead to a cacheTruncateMyCache followed by the
* bstTruncate LSS op. But for the moment, don't do anything.
*/
(void) TRUNCATE_BEAST(&genMsg, activity->decompStream.beast,
activity->decompStream.beastOffset);
}
#endif
compInfo->p.status &=
~(COMP_STATUS_UNCOMPRESSED|COMP_STATUS_COMPRESSED);
compInfo->p.status |= newCompState;
}
/* update the percentage space saved */
{
totalCompActivities++;
zASSERT(totalCompActivities >= 1);
if (totalCompActivities == 0)
{
totalCompActivities = 1;
}
num = activity->decompStream.beastSize - activity->compStream.beastSize;
X_LATCH(&CM_curCompStatistics.latch);
/* round the ratio */
CM_curCompStatistics.percentSpaceSaved =
(100 * num + activity->decompStream.beastSize / 2)/activity->decompStream.beastSize;
if (!CM_curCompStatistics.averageCompRatio)
{
/* we don't store averageCompRatio persistently, let's
* fake something if this is the first time
*/
CM_curCompStatistics.averageCompRatio
= CM_curCompStatistics.percentSpaceSaved;
}
else
{
/* round the ratio */
num = CM_curCompStatistics.percentSpaceSaved +
CM_curCompStatistics.averageCompRatio * (totalCompActivities - 1);
CM_curCompStatistics.averageCompRatio =
(num + totalCompActivities / 2)/totalCompActivities;
}
displayCompRatio();
UNX_LATCH(&CM_curCompStatistics.latch);
}
/* Update precious counts and cleanup the datastream if necessary. */
localXaction = COMN_BeginXLocal(uncompBeast);
++ compInfo->p.Cprecious;
if (! activity->keepSrcChunk)
{
if (-- compInfo->p.UCprecious == 0)
{
/* remove activity from uncompBeast->CM_activities list. */
DQ_RMV(activity, beastActivitiesChain);
/* wakeup all threads waiting for this activity to finish */
CM_signalEvent((ADDR)&compInfo->CM_activities, zOK);
/* beast is fully compressed now, modify its compression related
* information
*/
setBeastCompAttr(uncompBeast, zFA_DATA_STREAM_IS_COMPRESSED, localXaction, FALSE);
setVolCompStats(uncompBeast, compBeast, localXaction, TRUE);
if (compCleanup(&genMsg, uncompBeast, compBeast, FALSE, &localXaction) != zOK)
{
/* roll back compression related stats and attributes */
if (localXaction == NULL)
{
localXaction = COMN_BeginXLocal(uncompBeast);
}
compInfo->p.UCprecious++;
compInfo->p.status |= COMP_STATUS_UNCOMPRESSED;
// compInfo->p.Cprecious--;
setBeastCompAttr(uncompBeast, 0, localXaction, TRUE);
setVolCompStats(uncompBeast, compBeast, localXaction, FALSE);
updateBeastPurgeableBlksCnt(&genMsg,
(NamedBeast_s *)uncompBeast, compBeast, TRUE, localXaction);
}
goto releaseBeastsAndExit;
}
}
}
else
{
newCompState = COMP_STATUS_UNCOMPRESSED;
if (activity->keepSrcChunk)
newCompState |= COMP_STATUS_COMPRESSED;
if (compInfo->p.chunkSize > 0)
{
/* reset compStream.beastOffset, beastSize to include the entire
* chunk (including chunk hdr) i.e.,
* hdrSize = sizeof(CompChunkHdr_s);
* compStream.beastOffset -= hdrSize;
* compStream.beastSize += hdrSize;
*
* flush to disk, all uncompBeast blocks in the range
* <decompStream.beastOffset, decompStream.beastSize>.
*
* if uncompBeast is not marked for "Immediate Compression",
* {
* Throw away the compressed version of the chunk data:
* create a hole in the compBeast in the range
* <compStream.beastOffset, compStream.beastSize>
* This step may not be possible with current NSS
* implementation. In case of whole file compression, truncate
* the beast.
* }
*/
(void) setBeastChunkValidRange(&genMsg,
activity->decompStream.beast,
compInfo->p.chunkSize,
activity->decompStream.beastOffset,
activity->decompStream.beastSize);
setChunkCompStatus(&genMsg, activity->compStream.beast, offset,
compInfo->p.chunkSize, newCompState);
/* Flush all modified data to disk */
/* We must unlatch/latch compBeast/uncompBeast in order.
* The rule is if doing unlatching, unlatch compBeast before unlatching uncompBeast;
* if doing latching, latch uncompBeast before latching compBeast
*/
UNXLATCH_BEAST(compBeast);
UNXLATCH_BEAST(uncompBeast);
// BST_flush(compBeast);
BST_flush(uncompBeast);
XLATCH_BEAST(uncompBeast);
XLATCH_BEAST(compBeast);
}
else
{
/* We must unlatch/latch compBeast/uncompBeast in order.
* The rule is if doing unlatching, unlatch compBeast before unlatching uncompBeast;
* if doing latching, latch uncompBeast before latching compBeast
*/
UNXLATCH_BEAST(compBeast);
UNXLATCH_BEAST(uncompBeast);
BST_flush(uncompBeast);
XLATCH_BEAST(uncompBeast);
XLATCH_BEAST(compBeast);
compInfo->p.status &=
~(COMP_STATUS_UNCOMPRESSED|COMP_STATUS_COMPRESSED|COMP_STATUS_FAILURE);
compInfo->p.status |= newCompState;
if (! activity->keepSrcChunk)
{
/* Seems it is not necessary. */
/* Discard compressed data */
(void) TRUNCATE_BEAST(&genMsg, activity->compStream.beast,
(activity->compStream.beastOffset
+ activity->compStream.beastSize));
}
}
localXaction = COMN_BeginXLocal(uncompBeast);
if (compInfo->p.UCprecious == 0)
{
/* beast was fully compressed previously, modify compression
* related information since its uncompressed version
* is presented now
*/
setBeastCompAttr(uncompBeast, 0, localXaction, FALSE);
setVolCompStats(uncompBeast, compBeast, localXaction, FALSE);
}
/* Update precious counts and cleanup the datastream if necessary. */
++ compInfo->p.UCprecious;
if (! activity->keepSrcChunk)
{
if (-- compInfo->p.Cprecious == 0)
{
/* remove activity from uncompBeast->CM_activities list. */
DQ_RMV(activity, beastActivitiesChain);
/* wakeup all threads waiting for this activity to finish */
CM_signalEvent((ADDR)&compInfo->CM_activities, zOK);
if (decompCleanup(&genMsg, uncompBeast, compBeast, FALSE, localXaction) == zOK)
{
compBeast = 0;
}
/* compInfo will be released by decompCleanup */
// else if ((compInfo = BEAST_CM_INFO(uncompBeast)) != NULL)
// {
// /* roll back the modified compression related information */
// setBeastCompAttr(uncompBeast, zFA_DATA_STREAM_IS_COMPRESSED, localXaction, TRUE);
// setVolCompStats(uncompBeast, compBeast, localXaction, TRUE);
// }
goto releaseBeastsAndExit;
}
}
}
COMN_MARK_BEAST_XLOCAL(uncompBeast, localXaction);
if (COMN_ForceBeastWrite(&genMsg, uncompBeast, localXaction) != zOK)
{
zASSERT("COMN_ForceBeastWrite failed" == 0);
ClearErrno(&genMsg);
}
cleanupAndExit:
/* remove activity from uncompBeast->CM_activities list. */
DQ_RMV(activity, beastActivitiesChain);
if (DQ_EMPTY(&compInfo->CM_activities))
updateBeastPurgeableBlksCnt(&genMsg, (NamedBeast_s *)uncompBeast,
compBeast, TRUE, localXaction);
/* wakeup all threads waiting for this activity to finish */
CM_signalEvent((ADDR)&compInfo->CM_activities, zOK);
releaseBeastsAndExit:
if (localXaction)
{
COMN_EndXLocal(uncompBeast, &localXaction);
}
if (compBeast)
COMN_UnlatchAndRelease(&compBeast, XLATCHED);
COMN_UnlatchAndRelease(&uncompBeast, XLATCHED);
}
STATIC void CM_activityAborted(CMActivity_s *activity, STATUS errCode)
{
RootBeast_s *uncompBeast = activity->decompStream.beast;
RootBeast_s *compBeast = activity->compStream.beast;
CompressInfo_s *compInfo = BEAST_CM_INFO(uncompBeast);
QUAD offset = activity->decompStream.beastOffset;
NINT status;
GeneralMsg_s genMsg;
Xaction_s *localXaction = NULL;
ASSERT_MPKNSS_LOCK();
XLATCH_BEAST(uncompBeast);
XLATCH_BEAST(compBeast);
COMN_SETUP_GENERAL_MSG_NOSA(&genMsg);
DQ_RMV(activity, beastActivitiesChain);
activity->state = CM_ACTIVITY_STATE_FINISHED;
if (activity->op == CM_ACTIVITY_OP_COMPRESS)
{
status = COMP_STATUS_UNCOMPRESSED;
if (errCode != zERR_CM_ABORTED)
{
status |= COMP_STATUS_FAILURE;
}
if (compInfo->p.chunkSize > 0)
{
/*
* reset compStream.beastOffset, beastSize to include the entire
* chunk (including hdr) i.e.,
* hdrSize = sizeof(CompChunkHdr_s);
* compStream.beastOffset -= hdrSize;
* compStream.beastSize += hdrSize;
*
* * throw away the partially compressed chunk data
* create a hole in the compBeast in the range
* <compStream.beastOffset, compStream.beastSize>
* This step may not be possible with current NSS implementation.
* set chunk status to CantCompress;
*/
setChunkCompStatus(&genMsg, activity->compStream.beast, offset,
compInfo->p.chunkSize, status);
}
else
{
localXaction = COMN_BeginXLocal(uncompBeast);
compInfo->p.status &= ~COMP_STATUS_COMPRESSED;
compInfo->p.status = status;
if (errCode != zERR_CM_ABORTED)
{
setBeastCompAttr(uncompBeast, zFA_CANT_COMPRESS_DATA_STREAM, localXaction, FALSE);
}
}
if (!(compInfo->p.action & COMP_ACTION_ENABLE_IO_WRITE)
&& (compInfo->p.Cprecious == 0))
{
/* Wakeup all threads waiting for this activity to finish. */
// DQ_RMV(activity, beastActivitiesChain);
CM_signalEvent((ADDR)&compInfo->CM_activities, errCode);
/* we don't set up beast compression related attributes because we
* know it's cleaned up during compSetup. Also, we don't need to
* update volume comp blocks stats */
if (decompCleanup(&genMsg, uncompBeast, compBeast, FALSE, localXaction) == zOK)
{
compBeast = 0;
}
goto releaseBeastsAndExit;
}
}
else
{
status = COMP_STATUS_COMPRESSED;
if (errCode != zERR_CM_ABORTED)
{
status |= COMP_STATUS_FAILURE;
}
if (compInfo->p.chunkSize > 0)
{
/*
* throw away the partially decompressed chunk data
* create a hole in the uncompBeast in the range
* <decompStream.beastOffset, decompStream.beastSize>
* This step may not be possible with current NSS implementation.
* In case of whole file compression, truncate the beast.
*/
setChunkCompStatus(&genMsg, activity->compStream.beast, offset,
compInfo->p.chunkSize, status);
}
else
{
localXaction = COMN_BeginXLocal(uncompBeast);
compInfo->p.status &= ~COMP_STATUS_UNCOMPRESSED;
compInfo->p.status |= status;
}
if (compInfo->p.UCprecious == 0)
{
setBeastCompAttr(uncompBeast, zFA_DATA_STREAM_IS_COMPRESSED, localXaction, FALSE);
/* we don't need to update volume comp blocks stats */
compCleanup(&genMsg, uncompBeast, compBeast, FALSE, &localXaction);
}
}
if (localXaction)
{
COMN_MARK_BEAST_XLOCAL(uncompBeast, localXaction);
if (COMN_ForceBeastWrite(&genMsg, uncompBeast, localXaction) != zOK)
{
zASSERT("COMN_ForceBeastWrite failed" == 0);
ClearErrno(&genMsg);
}
}
// DQ_RMV(activity, beastActivitiesChain);
if (DQ_EMPTY(&compInfo->CM_activities))
{
updateBeastPurgeableBlksCnt(&genMsg, (NamedBeast_s *)uncompBeast,
compBeast, TRUE, localXaction);
}
/* Wakeup all threads waiting for this activity to finish. */
CM_signalEvent((ADDR)&compInfo->CM_activities, errCode);
releaseBeastsAndExit:
if (localXaction)
{
COMN_EndXLocal(uncompBeast, &localXaction);
}
if (compBeast)
{
COMN_UnlatchAndRelease(&compBeast, XLATCHED);
}
COMN_UnlatchAndRelease(&uncompBeast, XLATCHED);
}
void CM_activityWorkToDoRun(FsmLite_s *workToDoFsm, ADDR unused)
{
STATUS rc;
CMActivity_s *activity = STRUCT(workToDoFsm, CMActivity_s, fsm);
ASSERT_MPKNSS_LOCK();
rc = ALGOMGR_invokeCompAlgo(activity);
if (rc != zOK)
CM_activityAborted(activity, rc);
else CM_activityDone(activity);
zASSERT(NEXT(&activity->allActivitiesChain) != NULL);
CM_threadExit(activity);
}
void CM_activitySuspend(CMActivity_s *activity)
{
ASSERT_MPKNSS_LOCK();
switch (activity->state)
{
case CM_ACTIVITY_STATE_RUNNABLE:
case CM_ACTIVITY_STATE_RUNNING:
activity->state = CM_ACTIVITY_STATE_SUSPENDED;
break;
default:
break;
}
}
void CM_activityResume(CMActivity_s *activity)
{
ASSERT_MPKNSS_LOCK();
switch (activity->state)
{
case CM_ACTIVITY_STATE_RUNNABLE:
case CM_ACTIVITY_STATE_RUNNING:
break;
case CM_ACTIVITY_STATE_SUSPENDED:
activity->state = CM_ACTIVITY_STATE_RUNNABLE;
CM_signalEvent((ADDR)activity, zOK);
break;
default:
break;
}
}
void CM_activityAbort(CMActivity_s *activity, STATUS errCode, BOOL wait)
{
ASSERT_MPKNSS_LOCK();
switch (activity->state)
{
case CM_ACTIVITY_STATE_RUNNABLE:
case CM_ACTIVITY_STATE_RUNNING:
activity->state = CM_ACTIVITY_STATE_ABORTING;
break;
case CM_ACTIVITY_STATE_SUSPENDED:
activity->state = CM_ACTIVITY_STATE_ABORTING;
CM_signalEvent((ADDR)activity, errCode);
break;
default:
break;
}
}

View File

@@ -0,0 +1,568 @@
/****************************************************************************
|
| (C) Copyright 1985, 1991, 1993, 1996-1999 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
|
|***************************************************************************
|
| NSS Compression Management module
|
|---------------------------------------------------------------------------
|
| $Author: vandana $
| $Date: 2005-04-15 23:10:59 +0530 (Fri, 15 Apr 2005) $
|
| $RCSfile$
| $Revision: 937 $
|
|---------------------------------------------------------------------------
| Module Description:
|
+-------------------------------------------------------------------------*/
#include "cmDefs.h"
#include "cmRuntime.h"
#include "cmActivity.h"
#include "cmAlgoMan.h"
#include "cmControl.h"
#include "comnCompress.h"
typedef struct CompAlgo_s
{
BYTE algoID;
BYTE state;
#define COMP_ALGO_STATE_UNREGISTERED 0
#define COMP_ALGO_STATE_REGISTERED 1
#define COMP_ALGO_STATE_UNREGISTERING 2
CompAlgoIF_s *ops;
} CompAlgo_s;
CompAlgo_s CompAlgoTable[NSS_MAX_COMP_ALGORITHMS] =
{
{NSS_COMP_ALGO_ID_NETWARE, COMP_ALGO_STATE_UNREGISTERED, 0},
{NSS_COMP_ALGO_ID_COPY, COMP_ALGO_STATE_UNREGISTERED, 0},
};
void *ALGOMGR_malloc(size_t size)
{
void *mem;
MPKNSS_LOCK();
mem = malloc(size);
MPKNSS_UNLOCK();
return mem;
}
void ALGOMGR_free(void *mem)
{
MPKNSS_LOCK();
free(mem);
MPKNSS_UNLOCK();
}
/*
* Called by the algorithm after it is loaded.
*/
STATUS
ALGOMGR_registerCompAlgo(BYTE algoID, CompAlgoIF_s *algoIF)
{
STATUS rc;
MPKNSS_LOCK();
tryAgain: ;
switch (CompAlgoTable[algoID].state)
{
case COMP_ALGO_STATE_REGISTERED:
return zERR_CM_COMP_ALGO_ALREADY_REGISTERED;
case COMP_ALGO_STATE_UNREGISTERING:
rc = CM_awaitEvent((ADDR)&CompAlgoTable[algoID]);
if (rc != zOK)
goto functionExit;
goto tryAgain;
case COMP_ALGO_STATE_UNREGISTERED:
break;
default:
break;
}
CompAlgoTable[algoID].algoID = algoID;
CompAlgoTable[algoID].ops = algoIF;
MPKNSS_UNLOCK();
rc = CompAlgoTable[algoID].ops->init();
MPKNSS_LOCK();
if (rc != zOK)
goto functionExit;
CompAlgoTable[algoID].state = COMP_ALGO_STATE_REGISTERED;
functionExit: ;
MPKNSS_UNLOCK();
return rc;
}
/*
* Called by NSS before unloading an algorithm
*/
STATUS
ALGOMGR_unregisterCompAlgo(BYTE algoID, BOOL abortOngoingActivities, BOOL wait)
{
tryAgain: ;
switch (CompAlgoTable[algoID].state)
{
case COMP_ALGO_STATE_REGISTERED:
CompAlgoTable[algoID].state = COMP_ALGO_STATE_UNREGISTERING;
break;
case COMP_ALGO_STATE_UNREGISTERING:
if (wait)
{
(void) CM_awaitEvent((ADDR)&CompAlgoTable[algoID]);
goto tryAgain;
}
else return zOK;
case COMP_ALGO_STATE_UNREGISTERED:
return zOK;
default:
break;
}
for (;;)
{
CMActivity_s *activity;
NINT waitCount = 0;
DQ_FOREACH(&CM_activities, activity, CMActivity_s, allActivitiesChain)
{
switch (activity->state)
{
case CM_ACTIVITY_STATE_AVAILABLE:
case CM_ACTIVITY_STATE_ABORTED:
case CM_ACTIVITY_STATE_FINISHED:
continue;
default:
break;
}
if (abortOngoingActivities && (activity->algoID == algoID))
activity->state = CM_ACTIVITY_STATE_ABORTING;
++ waitCount;
}
/*
* Wait till all the ongoing (de)compressions finish.
*/
if (waitCount == 0)
break;
else if (! wait)
return zOK;
(void) CM_awaitEvent((ADDR)&CompAlgoTable[algoID]);
}
/* Call the algorithm's uninit() routine */
MPKNSS_UNLOCK();
CompAlgoTable[algoID].ops->uninit();
MPKNSS_LOCK();
CompAlgoTable[algoID].ops = NULL;
CompAlgoTable[algoID].state = COMP_ALGO_STATE_UNREGISTERED;
/*
* Signal any waiters that we are done.
*/
CM_signalEvent((ADDR)&CompAlgoTable[algoID], zOK);
return zOK;
}
STATUS
ALGOMGR_init(void *voidVol)
{
if (voidVol)
{
/*
* FixFixFix:
* Here we should check if all compression algorithms potentially used
* by the volume are loaded and if not, load them.
* But for the moment, who cares!
*/
// zASSERT("Hey this is not supported!" == NULL);
return zOK;
}
else if (CM_defaultAlgoStartupFn != NULL)
{
STATUS rc;
MPKNSS_UNLOCK();
rc = (* CM_defaultAlgoStartupFn)();
MPKNSS_LOCK();
return rc;
}
return zOK;
}
void
ALGOMGR_uninit(void *voidVol, BOOL abortOngoingActivities, BOOL wait)
{
SNINT i;
if (voidVol)
{
/*
* FixFixFix:
* Here we should unload any algorithms that are only used by this
* volume.
*/
// zASSERT("Hey this is not supported yet!" == NULL);
}
else
{
for (i = 0; i < NSS_MAX_COMP_ALGORITHMS; ++ i)
ALGOMGR_unregisterCompAlgo(i, abortOngoingActivities, wait);
}
}
#if zLINUX
#define LinuxCMStream_t (CMStream_t)
#else
#define LinuxCMStream_t
#endif
STATUS
ALGOMGR_invokeCompAlgo(CMActivity_s *activity)
{
BYTE algoID = activity->algoID;
BYTE algoVersion = activity->algoVersion;
BYTE minPercentGain = CM_curCompControlParams.minPercentGain;
STATUS rc;
switch (CompAlgoTable[algoID].state)
{
case COMP_ALGO_STATE_REGISTERED:
break;
case COMP_ALGO_STATE_UNREGISTERED:
case COMP_ALGO_STATE_UNREGISTERING:
default:
return zERR_CM_COMP_ALGO_NOT_REGISTERED;
}
MPKNSS_UNLOCK();
if (activity->op == CM_ACTIVITY_OP_COMPRESS)
{
rc = CompAlgoTable[algoID].ops->compressStream(algoVersion,
LinuxCMStream_t &activity->decompStream,
LinuxCMStream_t &activity->compStream,
LinuxCMStream_t &activity->tmpStream, minPercentGain);
}
else
{
rc = CompAlgoTable[algoID].ops->uncompressStream(algoVersion,
LinuxCMStream_t &activity->compStream,
LinuxCMStream_t &activity->decompStream);
}
MPKNSS_LOCK();
if (rc != zOK)
activity->state = CM_ACTIVITY_STATE_ABORTING;
switch (activity->state)
{
case CM_ACTIVITY_STATE_ABORTING:
activity->state = CM_ACTIVITY_STATE_ABORTED;
break;
case CM_ACTIVITY_STATE_RUNNING:
activity->state = CM_ACTIVITY_STATE_FINISHED;
default:
break;
}
if (CompAlgoTable[algoID].state == COMP_ALGO_STATE_UNREGISTERING)
CM_signalEvent((ADDR)&CompAlgoTable[algoID], zOK);
return rc;
}
STATUS
ALGOMGR_fetchStreamBuf(
CMStream_t streamHandle,
QUAD offset,
CMBuffer_t *cmbuf, /* out */
LONG mode,
LONG sizeRequested,
BYTE **data, /* out; ptr to reqd data in the buffer */
LONG *sizeReturned,/* out */
LONG *isHole) /* out */
{
STATUS rc;
QUAD realOffset;
SQUAD realSize;
CMStream_s *stream;
CMActivity_s *activity;
Blknum_t realBlknum;
GeneralMsg_s genMsg;
MPKNSS_LOCK();
if (! ISVALID_HANDLE(streamHandle))
{
rc = zERR_CM_INVALID_STREAM_HANDLE;
goto functionExit;
}
stream = streamHandle.stream;
activity = stream->activity;
/* Perform activity suspend/resume/abort control */
tryAgain: ;
switch (activity->state)
{
case CM_ACTIVITY_STATE_ABORTING:
rc = zERR_CM_ABORTED;
goto functionExit;
case CM_ACTIVITY_STATE_SUSPENDED:
/* Block this thread on this activity;
* to be awakened when the activity is resumed */
(void) CM_awaitEvent((ADDR) activity);
goto tryAgain;
default:
break;
}
COMN_SETUP_GENERAL_MSG_NOSA(&genMsg);
/* Clip size to read against chunk size */
*sizeReturned = sizeRequested;
realSize = stream->beastSize - offset;
if (realSize > sizeRequested)
realSize = sizeRequested;
realOffset = stream->beastOffset + offset;
{
/* Clip realSize against actual readable size within the buffer */
LONG readableSize = realOffset &
((1 << stream->beast->blkSizeShift) - 1);
readableSize = (1 << stream->beast->blkSizeShift) - readableSize;
if (realSize > readableSize)
realSize = readableSize;
}
if (realSize <= 0)
{
*sizeReturned = 0;
rc = zERR_END_OF_FILE;
goto functionExit;
}
/*
* realSize bytes at realOffset in beast can be actually supplied to
* the caller. Now do the actual I/O.
*/
if (mode == CACHE_READ)
{
SLATCH_BEAST(stream->beast);
}
else
{
XLATCH_BEAST(stream->beast);
}
rc = zOK;
realBlknum = realOffset >> stream->beast->blkSizeShift;
if (mode == CACHE_READ)
{
if (stream->curHoleBlks > 0)
{
Blknum_t holeStart = (stream->streamOffset + stream->beastOffset)
>> stream->beast->blkSizeShift;
if ((realBlknum >= holeStart) &&
(realBlknum < (holeStart + stream->curHoleBlks)))
*isHole = TRUE;
}
else
{
cmbuf->buffer = CM_fetchFileBlk(&genMsg, stream->beast, realBlknum,
mode, &stream->curHoleBlks);
if (! cmbuf->buffer)
{
rc = GetErrno(&genMsg);
goto unlatchBeastAndReturn;
}
if (stream->curHoleBlks > 0)
{
*isHole = TRUE;
CACHE_RELEASE(cmbuf->buffer);
}
}
if (*isHole)
{
INVALIDATE_HANDLE(*cmbuf);
*data = NULL;
*sizeReturned = realSize;
stream->streamOffset = offset + realSize;
-- stream->curHoleBlks;
}
}
else
{
if (activity->op == CM_ACTIVITY_OP_DECOMPRESS)
{
genMsg.flags |= DO_NOT_CHECK_SPACE_QUOTA;
}
cmbuf->buffer = CM_fetchFileBlk(&genMsg, stream->beast, realBlknum,
mode, &stream->curHoleBlks);
if (! cmbuf->buffer)
rc = GetErrno(&genMsg);
*isHole = FALSE;
stream->curHoleBlks = 0;
}
if (cmbuf->buffer)
{
mapBufferPage(cmbuf->buffer);
*data = cmbuf->buffer->pBuf.data + realOffset %
(1 << cmbuf->buffer->bufSizeShift);
*sizeReturned = realSize;
stream->streamOffset = offset + realSize;
}
unlatchBeastAndReturn: ;
UNLATCH_BEAST(stream->beast);
functionExit: ;
MPKNSS_UNLOCK();
return rc;
}
STATUS
ALGOMGR_releaseStreamBuf(
CMStream_t streamHandle,
CMBuffer_t cmbuf,
BOOL isdirty)
{
STATUS rc;
CMStream_s *stream;
CMActivity_s *activity;
MPKNSS_LOCK();
if (! ISVALID_HANDLE(streamHandle)) {
rc = zERR_CM_INVALID_STREAM_HANDLE;
goto functionExit;
}
if (! ISVALID_HANDLE(cmbuf)) {
rc = zERR_CM_INVALID_BUFFER_HANDLE;
goto functionExit;
}
stream = streamHandle.stream;
if (cmbuf.buffer)
{
unmapBufferPage(cmbuf.buffer);
if (isdirty)
CACHE_DIRTY_RELEASE(cmbuf.buffer);
else CACHE_RELEASE(cmbuf.buffer);
}
/* Perform activity suspend/resume/abort control */
activity = stream->activity;
/* Update sizeDone (size of target stream already (de)compressed) */
if (activity->op == CM_ACTIVITY_OP_DECOMPRESS)
{
if (stream == &activity->decompStream)
{
CompressInfo_s *compInfo = BEAST_CM_INFO(stream->beast);
activity->sizeDone += (1 << stream->beast->blkSizeShift);
zASSERT(compInfo);
UNCOMP_DATA_AVAILABLE(&compInfo->dataWaiters, stream->beastOffset,
activity->sizeDone);
}
}
else
{
if (stream == &activity->compStream)
activity->sizeDone += (1 << stream->beast->blkSizeShift);
}
tryAgain: ;
switch (activity->state)
{
case CM_ACTIVITY_STATE_ABORTING:
rc = zERR_CM_ABORTED;
goto functionExit;
case CM_ACTIVITY_STATE_SUSPENDED:
/* Block this thread on this activity;
* to be awakened when the activity is resumed */
(void) CM_awaitEvent((ADDR) activity);
goto tryAgain;
default:
break;
}
rc = zOK;
functionExit: ;
MPKNSS_UNLOCK();
return rc;
}
/*
* This operation truncates/pads the stream to given size.
* We delay the resizing till the end of the activity.
*/
STATUS
ALGOMGR_setStreamSize(CMStream_t streamHandle, QUAD size)
{
CMStream_s *stream;
MPKNSS_LOCK();
stream = streamHandle.stream;
stream->beastSize = size;
MPKNSS_UNLOCK();
return zOK;
}
QUAD
ALGOMGR_getStreamSize(CMStream_t streamHandle)
{
QUAD beastSize;
CMStream_s *stream;
MPKNSS_LOCK();
stream = streamHandle.stream;
beastSize = stream->beastSize;
MPKNSS_UNLOCK();
return beastSize;
}
STATUS
ALGOMGR_setStreamPosition(CMStream_t streamHandle, QUAD offset)
{
CMStream_s *stream;
MPKNSS_LOCK();
stream = streamHandle.stream;
stream->streamOffset = offset;
stream->curHoleBlks = 0;
MPKNSS_UNLOCK();
return zOK;
}
QUAD
ALGOMGR_getStreamPosition(CMStream_t streamHandle)
{
QUAD streamOffset;
CMStream_s *stream;
MPKNSS_LOCK();
stream = streamHandle.stream;
streamOffset = stream->streamOffset;
MPKNSS_UNLOCK();
return streamOffset;
}

View File

@@ -0,0 +1,537 @@
/****************************************************************************
|
| (C) Copyright 1985, 1991, 1993, 1996-1999 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
|
|***************************************************************************
|
| NSS Compression Management module
|
|---------------------------------------------------------------------------
|
| $Author: vandana $
| $Date: 2006-11-03 22:22:01 +0530 (Fri, 03 Nov 2006) $
|
| $RCSfile$
| $Revision: 1609 $
|
|---------------------------------------------------------------------------
| Module Description:
|
+-------------------------------------------------------------------------*/
#include "cmDefs.h"
#include "cmControl.h"
#include "cmNSS.h"
#include "alarm.h"
#include "nssPubs.h"
typedef struct CMBgCompressControl_s
{
BOOL inProgress; /* Background compression currently in progress */
BOOL scheduled; /* Background compression currently in progress */
WORD reason; /* Who started the background compression */
WORD unused; /* just for the alignment */
#define CM_BG_COMPRESS_REASON_NONE 0
#define CM_BG_COMPRESS_REASON_TIMER 1
#define CM_BG_COMPRESS_REASON_USER_REQUEST 2
OneShot_s alarm; /* Alarm for periodic background compression */
FsmLite_s fsm; /* thread on which background compression happens */
} CMBgCompressControl_s;
#define BG_COMPRESS_ABORTED(_bgCompress) (! (_bgCompress)->inProgress)
#define ABORT_BG_COMPRESS(_bgCompress) ((_bgCompress)->inProgress = FALSE)
#define MAX_ZIDS_PER_SCOOP 100
STATIC void CM_compressIdleFiles(Volume_s *volume, CMBgCompressControl_s *bgCompress)
{
typedef struct Stack_s {
Zid_t beastZids[MAX_ZIDS_PER_SCOOP];
} Stack_s;
Zid_t lastZidReturned;
GeneralMsg_s genMsg;
LONG i;
NINT numBeastsReturned;
NamedBeast_s *beast;
STATUS rc;
STACK_ALLOC();
ASSERT_MPKNSS_LOCK();
COMN_SETUP_GENERAL_MSG_NOSA(&genMsg);
lastZidReturned = zINVALID_ZID;
do
{
if (BG_COMPRESS_ABORTED(bgCompress))
{
STACK_FREE();
return;
}
/* Make sure the volume is in active state */
if (volume->v_statusFlag & VOL_SF_LEAVING_ACTIVE_STATE_CLEANUP)
{
STACK_FREE();
return;
}
/* Make sure compression is enabled on the volume */
if ((! CM_curCompControlParams.compEnabled) ||
(! (volume->VOLenabledAttributes & zATTR_COMPRESSION)))
{
STACK_FREE();
return;
}
if (volume->cmVolumeState.compActive != TRUE)
{
/* volume is deactivating */
STACK_FREE();
return;
}
/* Obtain a scoop of ZIDs to examine */
rc = volume->VOLcomnVolOps.VOL_browseBeastsInVolume(&genMsg, volume,
SELECT_BEASTS_FOR_COMPRESSION, MAX_ZIDS_PER_SCOOP,
&lastZidReturned, aStack->beastZids, &numBeastsReturned);
if (rc != zOK)
{
numBeastsReturned = 0;
ClearErrno(&genMsg);
}
/* Process each of the above beasts in turn */
for (i = 0; i < numBeastsReturned; ++ i)
{
if (volume->cmVolumeState.compActive != TRUE)
{
/* and if volume is deactivating */
STACK_FREE();
return;
}
/* Obtain the beast */
beast = (NamedBeast_s *)COMN_LookupByZid(&genMsg, volume,
aStack->beastZids[i], SLATCHED, TRUE);
/* Ignore all errors */
ClearErrno(&genMsg);
if (! beast)
continue;
/* Compress only beasts satisfying the following criteria */
if (COMN_IsDerivedFrom(beast, zFTYPE_NAMED_DATA_STREAM) &&
((beast->NAMEDattributes &
(zFA_SUBDIRECTORY|zFA_IS_LINK|zFA_DO_NOT_COMPRESS_FILE|
zFA_CANT_COMPRESS_DATA_STREAM)) == 0))
{
if (beast->NAMEDattributes & zFA_COMPRESS_FILE_IMMEDIATELY)
{
if ((beast->NAMEDattributes &
(zFA_DATA_STREAM_IS_COMPRESSED | zFA_CANT_COMPRESS_DATA_STREAM)) != 0)
{
goto skipBeast;
}
}
else if (beast->NAMEDattributes & zFA_DO_NOT_COMPRESS_FILE)
{
goto skipBeast;
}
else if (beast->NAMEDnameFlags & NFL_ADDED_TO_SALVAGE_TREE)
{
switch (CM_curCompControlParams.compressDeletedFilesOption)
{
case COMP_DELETED_FILES_NEVER:
goto skipBeast;
case COMP_DELETED_FILES_NEXT_DAY:
if (COMN_IsDerivedFrom(beast, zFTYPE_FILE) &&
(GetUTCTime() <
(((File_s *)beast)->FILEaccessedTime
+ CM_curCompControlParams.minDeletedFileIdleTime)))
{
goto skipBeast;
}
break;
default:
break;
}
}
else if (COMN_IsDerivedFrom(beast, zFTYPE_FILE) &&
(GetUTCTime() <
(((File_s *)beast)->FILEaccessedTime
+ CM_curCompControlParams.minFileIdleTime)))
{
goto skipBeast;
}
/* Check again if bgCompress is disabled by user. */
if (BG_COMPRESS_ABORTED(bgCompress) ||
(volume->cmVolumeState.compActive != TRUE))
{
COMN_UnlatchAndRelease(&beast, SLATCHED);
STACK_FREE();
return;
}
/* if parent won't allow compression, skip this beast */
if(!CM_checkParentDirForCompressOK(&genMsg, (File_s*)beast))
{
goto skipBeast;
}
/*
* Obtained a potential candidate for compression;
* Initiate its compression in the background and proceed.
*/
rc = CM_compressFileAsync(&genMsg, &beast->NAMEDroot,
SLATCHED, COMP_BACKGROUND);
if ((rc != zOK) && (GetErrno(&genMsg) == zERR_NO_MEMORY))
{
/*
* Couldn't queue for compression due to low memory.
* wait for some ongoing compressions to finish
* and try again.
*/
ClearErrno(&genMsg);
COMN_UnlatchAndRelease(&beast, SLATCHED);
LB_delay(100); // in milliseconds
-- i; /* Retry compressing same beast. */
continue;
}
}
skipBeast: ;
COMN_UnlatchAndRelease(&beast, SLATCHED);
PERIODIC_YIELD();
}
} while (numBeastsReturned == MAX_ZIDS_PER_SCOOP);
STACK_FREE();
}
void CM_bgCompressCleanUp()
{
CM_stopCompression(COMP_BACKGROUND);
}
void CM_bgCompressRun(CMBgCompressControl_s *bgCompress)
{
GeneralMsg_s dummyGenMsg;
Volume_s *prevVolume = NULL;
Volume_s *nextVolume;
ASSERT_MPKNSS_LOCK();
COMN_SETUP_GENERAL_MSG_NOSA(&dummyGenMsg);
/* Scan all known volumes for compression */
while (! BG_COMPRESS_ABORTED(bgCompress))
{
nextVolume = COMN_GetNextVolume(prevVolume);
if (prevVolume)
{
COMN_Release(&prevVolume);
}
if (nextVolume == NULL)
{
break;
}
prevVolume = nextVolume;
/* Start background compression on this volume */
if (COMN_LockVolumeActive(&dummyGenMsg, nextVolume, FALSE) == zOK)
{
CM_compressIdleFiles(nextVolume, bgCompress);
COMN_UnlockVolumeActive(nextVolume, FALSE);
}
}
if (prevVolume)
{
COMN_Release(&prevVolume);
}
if (BG_COMPRESS_ABORTED(bgCompress))
{
CM_bgCompressCleanUp();
}
else
{
bgCompress->inProgress = FALSE;
}
/* Set an alarm to start background compression at next interval */
if (bgCompress->reason == CM_BG_COMPRESS_REASON_USER_REQUEST)
{
CM_bgCompressRestartStartTimer(FALSE);
}
}
/* Forward declarations */
void CM_bgCompressStopTimerPopped(OneShot_s *alarm);
void CM_bgCompressStartTimerPopped(OneShot_s *alarm);
/*
* Seconds to elapse before the specified time of day,
* Wraps to next day if needed.
*/
STATIC LONG
SecondsToTimeOfDay(LONG targetTimeOfDay)
{
DOSTime_t dosTime = UTC2dosTime(GetUTCTime());
NINT hour = ((dosTime >> 11) & 0x1f);
NINT min = ((dosTime >> 5) & 0x3f);
NINT sec = ((dosTime & 0x1f) << 1);
NINT secOfDay = (hour * 60 + min) * 60 + sec;
SLONG waitSecs = targetTimeOfDay - secOfDay;
if (waitSecs < 0)
waitSecs += 24 * 60 * 60;
return (LONG) waitSecs;
}
STATIC void
CM_bgCompressWorkerThread(FsmLite_s *workToDoFsm, ADDR startCompress)
{
CMBgCompressControl_s *bgCompress =
STRUCT(workToDoFsm, CMBgCompressControl_s, fsm);
ASSERT_MPKNSS_LOCK();
bgCompress->scheduled = FALSE;
if ((BOOL)startCompress)
{
CM_bgCompressRun(bgCompress);
}
else
{
/* clean up any queued request */
CM_bgCompressCleanUp();
}
}
STATIC void
CM_startBgCompress(CMBgCompressControl_s *bgCompress)
{
ASSERT_MPKNSS_LOCK();
if (! bgCompress->scheduled && ! bgCompress->inProgress)
{
bgCompress->inProgress = TRUE;
bgCompress->scheduled = TRUE;
WORK_Schedule(&bgCompress->fsm, CM_bgCompressWorkerThread, (ADDR)TRUE);
}
}
STATIC void
CM_stopBgCompress(CMBgCompressControl_s *bgCompress)
{
ASSERT_MPKNSS_LOCK();
if (bgCompress->inProgress)
{
ABORT_BG_COMPRESS(bgCompress);
}
else
{
if (! bgCompress->scheduled)
{
/* clean up any queued request */
bgCompress->scheduled = TRUE;
WORK_Schedule(&bgCompress->fsm, CM_bgCompressWorkerThread, (ADDR)FALSE);
}
}
}
STATIC void
CM_bgCompressStartTimerPopped(OneShot_s *alarm)
{
CMBgCompressControl_s *bgCompress =
STRUCT(alarm, CMBgCompressControl_s, alarm);
ASSERT_MPKNSS_LOCK();
if (! bgCompress->inProgress)
{
LONG secsToStop = SecondsToTimeOfDay(
CM_curCompControlParams.dailyCheckStopTime);
if (! secsToStop)
return;
/* Set an alarm to stop background compression */
secOneShot(&bgCompress->alarm, secsToStop,
CM_bgCompressStopTimerPopped);
/* Start the background compression thread */
bgCompress->reason = CM_BG_COMPRESS_REASON_TIMER;
CM_startBgCompress(bgCompress);
}
}
STATIC void
CM_bgCompressStopTimerPopped(OneShot_s *alarm)
{
CMBgCompressControl_s *bgCompress =
STRUCT(alarm, CMBgCompressControl_s, alarm);
ASSERT_MPKNSS_LOCK();
if (bgCompress->reason == CM_BG_COMPRESS_REASON_TIMER)
{
LONG secsToStart = SecondsToTimeOfDay(
CM_curCompControlParams.dailyCheckStartTime);
/* Don't stop compression if next interval has already started */
if (! secsToStart)
return;
/* Stop the background compression thread */
CM_stopBgCompress(bgCompress);
/* Set an alarm to start background compression at next interval */
/* Cancel any previous timer */
CANCEL_ALARM(bgCompress->alarm);
secOneShot(&bgCompress->alarm, secsToStart,
CM_bgCompressStartTimerPopped);
}
}
STATIC CMBgCompressControl_s CM_bgCompressControl = {0};
void CM_bgCompressRestartStartTimer(BOOL startup)
{
LONG secsToStart = SecondsToTimeOfDay(
CM_curCompControlParams.dailyCheckStartTime);
ASSERT_MPKNSS_LOCK();
// Change of start timer only affects when bgCompression is not on progress
if (startup)
{
secOneShot(&CM_bgCompressControl.alarm,
secsToStart, CM_bgCompressStartTimerPopped);
}
else if (!CM_bgCompressControl.inProgress)
{
/* Cancel any previous timer */
if (ONESHOT_SET(CM_bgCompressControl.alarm))
{
CANCEL_ALARM(CM_bgCompressControl.alarm);
}
if (secsToStart > 0)
{
/* Set an alarm to start background compression at next interval */
secOneShot(&CM_bgCompressControl.alarm,
secsToStart, CM_bgCompressStartTimerPopped);
}
else CM_bgCompressStartTimerPopped(&CM_bgCompressControl.alarm);
}
}
void CM_bgCompressRestartStopTimer(BOOL startup)
{
LONG secsToStart = SecondsToTimeOfDay(
CM_curCompControlParams.dailyCheckStopTime);
ASSERT_MPKNSS_LOCK();
// Change of stop timer only affects when bgCompression is on progress
if (!startup)
{
if (CM_bgCompressControl.inProgress)
{
/* Cancel any previous timer */
if (ONESHOT_SET(CM_bgCompressControl.alarm))
{
CANCEL_ALARM(CM_bgCompressControl.alarm);
}
if (secsToStart > 0)
{
/* Set an alarm to start background compression at next interval */
secOneShot(&CM_bgCompressControl.alarm, secsToStart, CM_bgCompressStopTimerPopped);
}
else CM_bgCompressStopTimerPopped(&CM_bgCompressControl.alarm);
}
}
}
void
CM_bgCompressInit()
{
ASSERT_MPKNSS_LOCK();
CM_bgCompressControl.inProgress = FALSE;
CM_bgCompressControl.scheduled = FALSE;
CM_bgCompressControl.reason = CM_BG_COMPRESS_REASON_NONE;
INIT_ONESHOT(CM_bgCompressControl.alarm);
FSMLITE_INIT(&CM_bgCompressControl.fsm,
"FSM for background compression/decompression", 1);
}
/*
* Interface to explicitly request to start background compression.
*/
void
CM_bgCompressStartRequest()
{
ASSERT_MPKNSS_LOCK();
CM_bgCompressControl.reason = CM_BG_COMPRESS_REASON_USER_REQUEST;
CM_startBgCompress(&CM_bgCompressControl);
}
/*
* Interface to explicitly request to stop background compression.
*/
void
CM_bgCompressStopRequest()
{
ASSERT_MPKNSS_LOCK();
CM_stopBgCompress(&CM_bgCompressControl);
}
/*
* When UTC is changed (cause by change of time zone),
* we need to recompute bgcompression start and stop time
*/
void CM_bgCompressResetTimer()
{
ASSERT_MPKNSS_LOCK();
if (CM_bgCompressControl.inProgress)
{
CM_bgCompressRestartStopTimer(FALSE);
}
else
{
CM_bgCompressRestartStartTimer(FALSE);
}
}

View File

@@ -0,0 +1,161 @@
/****************************************************************************
|
| (C) Copyright 1985, 1991, 1993, 1996-1999 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
|
|***************************************************************************
|
| NSS Compression Management module
|
|---------------------------------------------------------------------------
|
| $Author: taysom $
| $Date: 2004-12-31 01:10:58 +0530 (Fri, 31 Dec 2004) $
|
| $RCSfile$
| $Revision: 465 $
|
|---------------------------------------------------------------------------
| Module Description:
|
+-------------------------------------------------------------------------*/
#include "cmDefs.h"
#include "cmAlgoMan.h"
#include "cmActivity.h"
#include "cmRuntime.h"
#include "cmControl.h"
#include "cmNSS.h"
CMCompControlParams_s CM_curCompControlParams =
{
0,
0,
5,
10,
0,
24 * 60 * 60,
TRUE,
MAX_ZIDS_QUEUED_FOR_COMPRESSION,
20,
DECOMP_OPTION_LEAVE_DECOMPRESSED_FOR_N_ACCESSES,
COMP_DELETED_FILES_NEXT_DAY,
0,
31 * 60 + 18,
};
void CM_controlCompression(BOOL enable)
{
/* Compression Enabled flag has changed */
if (enable != CM_curCompControlParams.compEnabled)
{
CM_curCompControlParams.compEnabled = enable;
if (enable)
{
/*
* Start all the pending requests.
*/
CM_startPendingCompressions();
}
else
{
/*
* Even if compression is disabled on this server, we let all ongoing
* activities to finish, as otherwise they might hold up precious
* resources.
*/
}
}
}
void CM_controlMaxConcurrentComp(NINT value)
{
CM_curCompControlParams.maxCompressions = value;
CM_threadsChange();
CM_activityPoolChange();
}
CMCompStatistics_s CM_curCompStatistics;
STATUS getCompStatistics(CMCompStatistics_s *stats)
{
*stats = CM_curCompStatistics;
return zOK;
}
STATIC VolumeCompAttr_s CM_defaultVolumeCompAttributes =
{
NSS_COMP_IMPL_MAJOR_VERSION,
NSS_COMP_IMPL_MINOR_VERSION,
NSS_COMP_ALGO_ID_NETWARE,
NETWARE_COMP_ALGO_VERSION,
0,
0,
(1 << NSS_COMP_ALGO_ID_NETWARE) | (1 << NSS_COMP_ALGO_ID_COPY),
};
/* Check that sizes are still correct. Needed for our
* COMPILER_NO_INCOMPLETE_OFFSETOF compilers as they will not
* calculate items at compile time.
*/
BYTE CHECK_CompRequestScoop_s_1[ (3 == COMP_REQUEST_SCOOP_UNUSED_WORD) ? 1 : 0 ];
BYTE CHECK_CompRequestScoop_s_2[ (510 == MAX_COMP_REQS_PER_SCOOP) ? 1 : 0 ];
BYTE CHECK_CompRequestScoop_s_3[ (4096 == sizeof(CompRequestScoop_s)) ? 1 : 0 ];
void CM_resetVolumeCompState(Volume_s *volume)
{
/* Initialize volume's persistent data */
volume->VOLcompAttributes = CM_defaultVolumeCompAttributes;
/* Initialize volume's logged persistent data */
volume->VOLnumCompressedFiles = 0;
volume->VOLnumCompDelFiles = 0;
volume->VOLnumUncompressibleFiles = 0;
volume->VOLnumCompressedFileBlocks = 0;
}
void CM_initVolumeCompState(Volume_s *volume)
{
/* remember the compFlags setting, volume modify routines calls this function.
* compFlags is set by ZLSS level, if we don't remember the flags and set
* them back after reset volume's compression state, we won't have chance
* to do it later
*/
LONG compFlags = volume->VOLcompAttributes.compFlags &
(VOL_COMP_FLAGS_UPGRADE_START | VOL_COMP_FLAGS_UPGRADE_FINISHED);
/* Initialize volume's persistent data */
CM_resetVolumeCompState(volume);
/* set back its previous compFlags setting */
volume->VOLcompAttributes.compFlags |= compFlags;
}
/* Interface to set Volume/file/directory Compression Attributes */
STATUS volSetCompAttr(Volume_s *volume, VolumeCompAttr_s *newAttr)
{
return zOK;
}
STATUS
CM_controlInit()
{
bzero(&CM_curCompStatistics, sizeof(CM_curCompStatistics));
CM_bgCompressInit();
return zOK;
}

View File

@@ -0,0 +1,68 @@
/****************************************************************************
|
| (C) Copyright 2001-2002 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 Loadable Storage Services (LSS) module
|
|---------------------------------------------------------------------------
|
| $Author: $
| $Date: $
|
| $RCSfile$
| $Revision: $
|
|---------------------------------------------------------------------------
| This module is used to:
+-------------------------------------------------------------------------*/
#ifndef _COMNAUDIT_H_
#define _COMNAUDIT_H_
#ifdef __cplusplus
extern "C" {
#endif
#ifndef AUDIT_KERNEL_OTHER
#define AUDIT_KERNEL_OTHER 1316
#endif
extern BOOL NSSLAF_AuditEnabled;
extern void NSSLAF_LogTrusteeChange(
GeneralMsg_s *genMsg,
NamingMsg_s *nameMsg,
LONG mode,
UserID_t *trustee,
NINT rights,
NINT attributes,
NINT inheritedRights);
#define NSSLAF_MODE_ADD_TRUSTEE 1
#define NSSLAF_MODE_REMOVE_TRUSTEE 2
#define NSSLAF_MODE_SET_INHERITED_RIGHTS 3
#ifdef __cplusplus
}
#endif
#endif /* #ifdef _COMNAUDIT_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,47 @@
/****************************************************************************
|
| (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 Advance File Services (NSS) module
|
|---------------------------------------------------------------------------
|
| $Author: taysom $
| $Date: 2004-12-31 01:10:58 +0530 (Fri, 31 Dec 2004) $
|
| $RCSfile$
| $Revision: 465 $
|
|---------------------------------------------------------------------------
| This module is used to:
| This defines globals and prototypes for the background checker.
+-------------------------------------------------------------------------*/
#ifndef _SEQUPDATER_H_
#define _SEQUPDATER_H_
#if zLINUX
extern void SEQ_StartProcess(void);
extern void SEQ_StopProcess(void);
extern void SEQ_Sleep(NINT seconds);
extern void SEQ_Wakeup(void);
#endif
#endif /* _SEQUPDATER_H_ */

View File

@@ -0,0 +1,527 @@
/****************************************************************************
|
| (C) Copyright 1995-2002 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) module
|
|---------------------------------------------------------------------------
|
| $Author: vandana $
| $Date: 2006-12-30 03:27:16 +0530 (Sat, 30 Dec 2006) $
|
| $RCSfile$
| $Revision: 1799 $
|
|---------------------------------------------------------------------------
| This module is used to:
| Implements Logical Volumes/Volume/Pools library routines. Contains
| routines that deal with the names of pools and volumes.
+-------------------------------------------------------------------------*/
#include <procdefs.h> /* NetWare */
#include <lfsproto.h> /* NetWare */
#include <mmpublic.h>
#include <guid.h> /* NSS Library */
#include <xError.h>
#include <stdio.h>
#include <stdlib.h>
#include <pssDebug.h>
#include <xUnicode.h>
#include <volume.h>
#include "mal.h" /* For POOL_MAXNAME */
#include "nssPubs.h"
/* ASCII numeric to unicode numeric table */
STATIC unicode_t *LB_UnicodeDigit[] = {
L"0",
L"1",
L"2",
L"3",
L"4",
L"5",
L"6",
L"7",
L"8",
L"9"
};
/*
* LB_VolumeNameToNewName() -
* Takes a current name (usually a volume name) and converts it
* to a snapshot name.
*
* Conversion examples (assumes posfixBase is L"_SV") -
* volName="NameName", uniSize=30, mangleKey = 0 then "NameName_SV"
* volName="NameName", uniSize=30, mangleKey = 1 then "NameName_SV001"
* volName="NameName", uniSize=10, mangleKey = 0 then "NameNa_SV"
* volName="NameName", uniSize=10, mangleKey = 1 then "Nam_SV001"
* volName="NameName", uniSize=10, mangleKey = 2 then "Nam_SV002"
* volName="NameNameName", uniSize=10, mangleKey = 0 then zERR_BUFFER_TOO_SMALL
* volName="Name", uniSize=8, mangleKey = 0 then zERR_BUFFER_TOO_SMALL
*
*
* Returns -
* zOK on success with mangleKey and newName changed.
* zERR_BUFFER_TOO_SMALL on failure with mangleKey and newName
* undefined. Can only get this error if newName is
* too small. Too small is either less than 7 unicode
* characters OR smaller than the passed in name.
*/
STATUS LB_VolumeNameToNewName(
CONST unicode_t *volName, /* Current volume name */
CONST unicode_t *postfixBase, /* Base 3 unicode length string to post fix */
NINT *mangleKey, /* (input/output)Mangle key pointer, must point to 0 on first call */
NINT uniSize, /* Number of unicode newName can hold */
unicode_t *newName ) /* (output)New mangled name */
{
NINT addedLen, location;
unicode_t postfixToAdd[10];
if ( unilen( postfixBase ) != 3 )
{
zASSERT("Illegal parameter passed to LB_VolumeNameToNewName()" == NULL );
return( zERR_BAD_PARAMETER_VALUE );
}
if ( uniSize < 7 ) /* Minimum requirement is to hold L"'postfixBase'xxx" */
{
return( zERR_BUFFER_TOO_SMALL );
}
if ( unilen( volName ) >= uniSize )
{
return( zERR_BUFFER_TOO_SMALL );
}
/**
* Normally, append postfixBase to current volume name to obtain new name.
* If this creates a name too long then the postfixBase will replace some
* of the end characters. The user can rename the new name if they
* wish.
*
* Mangle code changes postfixBase to 'postfixBase'xxx where xxx is a
* number starting at 1. The caller is responsible for determining a name
* clash and must then call us back with the mangle key we returned to
* them. We use 3 digits because 1000 attempts at a name is enough.
*/
if ( (*mangleKey) != 0 )
{
NINT index100, index10, index1;
unicpy( &postfixToAdd[0], postfixBase );
index100 = (*mangleKey)/100;
unicat( &postfixToAdd[0], LB_UnicodeDigit[ index100 % 10 ] );
index10 = ((*mangleKey) - index100 * 100 ) / 10;
unicat( &postfixToAdd[0], LB_UnicodeDigit[ index10 ] );
index1 = (*mangleKey) % 10;
unicat( &postfixToAdd[0], LB_UnicodeDigit[ index1 ] );
}
else
{
unicpy( &postfixToAdd[0], postfixBase );
}
addedLen = unilen( postfixToAdd );
/* Verify that we did not ZAP past the end of our internal buffer */
zASSERT( addedLen < ( sizeof( postfixToAdd )/ sizeof( postfixToAdd[0] )) );
if ( (unilen( volName ) + addedLen) < uniSize )
{
location = unilen( volName );
}
else
{
location = uniSize - addedLen - 1;
}
unicpy( newName, volName );
unicpy( &newName[location], &postfixToAdd[0] );
++(*mangleKey);
#if NSS_DEBUG IS_ENABLED
DBG_DebugPrintf(LRED,"Converted volume name is %U\r\n",newName);
#endif
return( zOK );
} /* End of LB_VolumeNameToNewName() */
/*
* LB_VolumeNameToSnapshotName() -
* Takes a current name (usually a volume name) and converts it
* to a snapshot name.
*
* Returns -
* zOK on success with mangleKey and snapName changed.
* zERR_BUFFER_TOO_SMALL on failure with mangleKey and snapName
* undefined. Can only get this error if snapName is
* too small. Too small is either less than 7 unicode
* characters OR smaller than the passed in name.
*/
STATUS LB_VolumeNameToSnapshotName(
CONST unicode_t *volName, /* Current volume name */
NINT *mangleKey, /* (input/output)Mangle key pointer, must point to 0 on first call */
NINT uniSize, /* Number of unicode snapName can hold */
unicode_t *snapName ) /* (output)New mangled name */
{
STATUS status;
status = LB_VolumeNameToNewName( volName, L"_SV", mangleKey, uniSize, snapName );
return( status );
} /* End of LB_VolumeNameToSnapshotName() */
/* See comments for LB_VolumeNameToSnapshotName */
STATUS LB_VolumeNameToQSName(
CONST unicode_t *volName, /* Current volume name */
NINT *mangleKey, /* (input/output)Mangle key pointer, must point to 0 on first call */
NINT uniSize, /* Number of unicode newName can hold */
unicode_t *newName ) /* (output)New mangled name */
{
STATUS status;
status = LB_VolumeNameToNewName( volName, L"_QS", mangleKey, uniSize, newName );
return( status );
} /* End of LB_VolumeNameToQSName() */
/*
* LB_VolumeNameToAutoRenameName() -
* Takes a current name (usually a volume name) and converts it
* to a AutoRename name.
*
* Returns -
* zOK on success with mangleKey and AutoRename Name changed.
* zERR_BUFFER_TOO_SMALL on failure with mangleKey and AutoRename
* Name undefined. Can only get this error if AutoRename
* Name is too small. Too small is either less than 7
* unicode characters OR smaller than the passed in name.
*/
STATUS LB_VolumeNameToAutoRenameName(
CONST unicode_t *volName, /* Current volume name */
NINT *mangleKey, /* (input/output)Mangle key pointer, must point to 0 on first call */
NINT uniSize, /* Number of unicode AutoRename Name can hold */
unicode_t *autoRenameName ) /* (output)New mangled name */
{
STATUS status;
status = LB_VolumeNameToNewName( volName, L"_AR", mangleKey, uniSize, autoRenameName );
return( status );
} /* End of LB_VolumeNameToAutoRenameName() */
/*
* LB_VolumeNameToPoolName() -
* Takes a current name (usually a volume name) and converts it
* to a pool name.
*
* Conversion examples -
* volName="NameName", uniSize=30, mangleKey = 0 then "NameName_Pool"
* volName="NameName", uniSize=30, mangleKey = 1 then "NameName_Pool001"
* volName="NameName", uniSize=10, mangleKey = 0 then "Name_Pool"
* volName="NameName", uniSize=10, mangleKey = 1 then "N_Pool001"
* volName="NameName", uniSize=10, mangleKey = 2 then "N_Pool002"
* volName="NameNameName", uniSize=10, mangleKey = 0 then zERR_BUFFER_TOO_SMALL
* volName="Name", uniSize=8, mangleKey = 0 then zERR_BUFFER_TOO_SMALL
*
*
* Returns -
* zOK on success with mangleKey and poolName changed.
* zERR_BUFFER_TOO_SMALL on failure with mangleKey and poolName
* undefined. Can only get this error if poolName is
* too small. Too small is either less than 9 unicode
* characters OR smaller than the passed in name.
*/
STATUS LB_VolumeNameToPoolName(
CONST unicode_t *volName, /* Current pool name */
NINT *mangleKey, /* (input/output)Mangle key pointer, must point to 0 on first call */
NINT uniSize, /* Number of unicode poolName can hold */
unicode_t *poolName ) /* (output)New mangled name */
{
#if 0
NINT addedLen, location;
unicode_t postfixToAdd[10];
#endif
if ( uniSize < 9 ) /* Minimum requirement is to hold L"_POOLxxx" */
{
return( zERR_BUFFER_TOO_SMALL );
}
if ( unilen( volName ) >= uniSize )
{
return( zERR_BUFFER_TOO_SMALL );
}
/**
* For now we will be keeping the same names for the POOL and
* VOLUME. Too much code assumes names from the MAL are VOLUME
* names. For example, NWCONFIG.
*/
unicpy( poolName, volName );
#if 0
/**
* Normally, append _POOL to current volume name to obtain pool's name.
* If this creates a name too long then the _POOL will replace some
* of the end characters. The user can rename the POOL name if they
* wish. Note that NSS/ZLSS requires that the POOL and VOLUME
* names be different.
*
* Mangle code changes _POOL to _POOLxxx where xxx is a number starting
* at 1. The caller is responsible for determining a name clash
* and must then call us back with the mangle key we returned to
* them. We use 3 digits because NetWare has a 255 Volume limit.
*/
if ( (*mangleKey) != 0 )
{
NINT index100, index10, index1;
unicpy( &postfixToAdd[0], L"_POOL" );
index100 = (*mangleKey)/100;
unicat( &postfixToAdd[0], LB_UnicodeDigit[ index100 % 10 ] );
index10 = ((*mangleKey) - index100 * 100 ) / 10;
unicat( &postfixToAdd[0], LB_UnicodeDigit[ index10 ] );
index1 = (*mangleKey) % 10;
unicat( &postfixToAdd[0], LB_UnicodeDigit[ index1 ] );
}
else
{
unicpy( &postfixToAdd[0], L"_POOL" );
}
addedLen = unilen( postfixToAdd );
/* Verify that we did not ZAP past the end of our internal buffer */
zASSERT( addedLen < ( sizeof( postfixToAdd )/ sizeof( postfixToAdd[0] )) );
if ( (unilen( volName ) + addedLen) < uniSize )
{
location = unilen( volName );
}
else
{
location = uniSize - addedLen - 1;
}
unicpy( poolName, volName );
unicpy( &poolName[location], &postfixToAdd[0] );
++(*mangleKey);
#endif
#if NSS_DEBUG IS_ENABLED
DBG_DebugPrintf(LRED,"Converted pool name is %U\r\n",poolName);
#endif
return( zOK );
} /* End of LB_VolumeNameToPoolName() */
/***
*** These defines bound the length of a volume name. They were
*** taken from the NSS Menu code.
***/
#define LB_VOLUME_NAME_SIZE_MIN 2
#define LB_VOLUME_NAME_SIZE_MAX 15
/***
*** This is a list of the valid characters that can be in a volume
*** name. This was taken from the NSS Menu code.
***/
STATIC char LB_VolumeCharsValid[] =
MSGNot("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_!@#$%&()");
/***
*** This is a list of volumes that can not be renamed.
***/
STATIC unicode_t *LB_VolumeNamesRenameNo[] =
{
AVOL_PERSISTENT_ADMIN_VOLUME_UNICODE,
AVOL_ADMIN_VOLUME_UNICODE,
NULL /* Must be last - indicates end of List */
};
/***
*** This is a list of reserved volume names. This was taken from the
*** NSS Menu code.
***/
STATIC char *LB_VolumeNamesReserved[] =
{
MSGNot("NUL"),
MSGNot("CON"),
MSGNot("AUX"),
MSGNot("PRN"),
MSGNot("COM1"),
MSGNot("COM2"),
MSGNot("COM3"),
MSGNot("COM4"),
MSGNot("LPT1"),
MSGNot("LPT2"),
MSGNot("LPT3"),
MSGNot("NETQ"),
MSGNot("PIPE"),
MSGNot("CLOCK"),
AVOL_ADMIN_VOLUME, /* Added because current name of NSS_Admin volume */
MSGNot("NSS_ADMIN"),
MSGNot("ALL"), /* Added to list since NSS likes to use 'ALL'
* in commands like "nss /act=all" to specify
* all volumes - Greg
*/
NULL /* Must be last - indicates end of List */
};
/*
* LB_VolumeNameValid() -
* Determines if a volume name is syntactically valid.
*
* This function performs numerous checks on the name to determine
* if the volume name is syntactically valid. This following tests are
* performed.
*
* 1). Name has valid characters (See LB_VolumeCharsValid global).
* 2). Not a reserved name (See LB_VolumeNamesReserved global).
* 3). At least 2 character long, but not more than 15.
* 4). Does not start or end with a underscore.
* 5). Does not contain consecutive underscores.
*
* Returns -
* zOK if name is syntactically valid else specific error code.
*
* Note -
* This code was taken from the menu code. Why the abovve tests
* are required are not known!
*/
STATUS LB_VolumeNameValid( unicode_t *volumeName )
{
NINT namelen;
char name[POOL_MAXNAME];
NINT retNameSize;
BOOL validName = FALSE;
NINT i,j;
/* The persistent admin volume is a special case because
* it starts with a '_' and is still LEGAL.
*/
if (unicmp(volumeName, AVOL_PERSISTENT_ADMIN_VOLUME_UNICODE) == 0)
{
return zOK;
}
bzero(name, sizeof(name));
LB_UnicodeToByte(NSS_UNI_CONVERSION_RAW, name, POOL_MAXNAME, volumeName, &retNameSize);
namelen = strlen(name);
if ( namelen < LB_VOLUME_NAME_SIZE_MIN )
{
return( zERR_BAD_VOLUME_NAME_SIZE_SHORT );
}
if ( namelen > LB_VOLUME_NAME_SIZE_MAX )
{
return( zERR_BAD_VOLUME_NAME_SIZE_LONG );
}
for (i = 0; i < namelen; i++)
{
validName = FALSE;
for (j = 0; j < sizeof(LB_VolumeCharsValid); j++)
{
if (name[i] == LB_VolumeCharsValid[j])
{
validName = TRUE;
break;
}
}
if (!validName)
{
break;
}
}
if (!validName)
{
return ( zERR_BAD_VOLUME_NAME_CHARACTER );
}
if ((name[0] == '_') || (name[namelen - 1] == '_'))
{
return (zERR_BAD_VOLUME_NAME_UNDERSCORE);
}
for (i = 0; i < (namelen - 1); i++)
{
if ((name[i] == '_') && (name[i+1] == '_'))
{
return (zERR_BAD_VOLUME_NAME_TWO_UNDERSCORES);
}
}
i = 0;
while (LB_VolumeNamesReserved[i] != NULL)
{
/* Note - we ignore case here */
if (stricmp(name, LB_VolumeNamesReserved[i]) == 0)
{
return( zERR_RESERVED_VOLUME_NAME );
}
i++;
}
return( zOK );
}
/*
* LB_VolumeRenameOK() -
* Determines if a volume can be renamed based on the volume's
* current name. Simply checks if the volume is one of the
* volume names that are not allowed to be renamed.
*
* Returns -
* zOK if volume can be renamed else specific error code.
*
*/
STATUS LB_VolumeRenameOK( unicode_t *currentVolumeName )
{
NINT i;
i = 0;
while (LB_VolumeNamesRenameNo[i] != NULL)
{ /* Note - we 'ignore case' here */
if (uniicmp(currentVolumeName, LB_VolumeNamesRenameNo[i]) == 0)
{
return( zERR_VOLUME_RENAME_NOT_ALLOWED );
}
i++;
}
return( zOK );
} /* End of LB_VolumeRenameOK() */

View File

@@ -0,0 +1,27 @@
/****************************************************************************
| Userspace COMN time boundary for imported NSS sources.
|
| public_core/nsslnxlib/nssLnxDummy.c implements GetCurrentTime() as Linux
| jiffies for the kernel-oriented NSS Linux support library. libnwnss runs
| in userspace, so expose the same NSS symbol using a monotonic clock tick
| counter rather than importing the full kernel nssLnxDummy.c shim.
+-------------------------------------------------------------------------*/
#include <time.h>
#include <public/zOmni.h>
LONG GetCurrentTime(void)
{
struct timespec ts;
if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
return 0;
}
return (LONG)(ts.tv_sec * 100UL + ts.tv_nsec / 10000000UL);
}
LONG GetHighResolutionTimer(void)
{
return GetCurrentTime();
}

View File

@@ -0,0 +1,14 @@
/****************************************************************************
| Selected NSS startup name globals for userspace libnwnss.
|
| These definitions are copied from public_core/nss/nssStartup.c. The full
| startup module owns NetWare/kernel module lifecycle, event registration and
| command-line machinery that is not part of the default userspace library
| boundary. Keep only the data globals required by the real COMN/AdminVolume
| imports until the full NSS startup block is imported deliberately.
+-------------------------------------------------------------------------*/
#include <public/zOmni.h>
unicode_t *PersistAdminVolUnicodeName = (unicode_t *)L"_ADMIN_P";
NINT AdminVolNameLen = 0;

View File

@@ -11,6 +11,9 @@
#include <library/xStdio.h>
#include <wio.h>
LONG GetCurrentTime(void);
LONG GetHighResolutionTimer(void);
#ifdef wPause
#undef wPause
#define wPause(_file, _mode) LB_wPause((WFile_s *)(void *)(_file), (_mode))
@@ -66,6 +69,28 @@ typedef LONG UINT32;
do { (void)(_producer); (void)(_event); } while (0)
#endif
#ifndef ZOS_StartThread
#define ZOS_StartThread(_thread, _name, _func, _stack, _prio, _arg) \
do { (void)(_name); (void)(_func); (void)(_stack); (void)(_prio); (void)(_arg); (_thread) = 0; } while (0)
#endif
#ifndef ZOS_StartThreadWithModuleHandle
#define ZOS_StartThreadWithModuleHandle(_thread, _name, _func, _stack, _prio, _arg, _module) \
do { (void)(_module); ZOS_StartThread((_thread), (_name), (_func), (_stack), (_prio), (_arg)); } while (0)
#endif
#ifndef ZOS_RegisterConsumer
#define ZOS_RegisterConsumer(_reg) \
do { (void)(_reg); } while (0)
#endif
#ifndef ZOS_UnRegisterConsumer
#define ZOS_UnRegisterConsumer(_consumer, _event) \
do { (void)(_consumer); (void)(_event); } while (0)
#endif
#ifndef ZOS_ImportPublicSymbol
#define ZOS_ImportPublicSymbol(_target, _module, _name) \
do { (void)(_module); (void)(_name); (_target) = NULL; } while (0)

File diff suppressed because it is too large Load Diff