/*
* Copyright 2000, International Business Machines Corporation and others.
* All Rights Reserved.
- *
+ *
* This software has been released under the terms of the IBM Public
* License. For details, see the LICENSE file in the top-level source
* directory or online at http://www.openafs.org/dl/license10.html
+ *
+ * Portions Copyright (c) 2006 Sine Nomine Associates
*/
-#include "fs_stats.h" /*File Server stats package*/
+#ifndef _AFS_VICED_HOST_H
+#define _AFS_VICED_HOST_H
+
+#include "fs_stats.h" /*File Server stats package */
#ifdef AFS_PTHREAD_ENV
/*
* precedence is host_listlock_mutex, host->mutex, host_glock_mutex.
*/
#include <rx/rx_globals.h>
-#include <assert.h>
+#include <afs/afs_assert.h>
#include <pthread.h>
extern pthread_mutex_t host_glock_mutex;
-#define H_LOCK \
- assert(pthread_mutex_lock(&host_glock_mutex) == 0);
-#define H_UNLOCK \
- assert(pthread_mutex_unlock(&host_glock_mutex) == 0);
+#define H_LOCK MUTEX_ENTER(&host_glock_mutex);
+#define H_UNLOCK MUTEX_EXIT(&host_glock_mutex);
+extern pthread_key_t viced_uclient_key;
#else /* AFS_PTHREAD_ENV */
#define H_LOCK
#define H_UNLOCK
#endif /* AFS_PTHREAD_ENV */
#define h_MAXHOSTTABLEENTRIES 1000
-#define h_HASHENTRIES 256 /* Power of 2 */
+#define h_HASHENTRIES 256 /* Power of 2 */
#define h_MAXHOSTTABLES 200
-#define h_HTSPERBLOCK 512 /* Power of 2 */
-#define h_HTSHIFT 9 /* log base 2 of HTSPERBLOCK */
-
-#define h_threadsPerSlot 32 /* bits per afs_int32 */
-#define h_threadsShift 5 /* for multiply/divide */
-#define h_threadsMask 31 /* for remainder */
+#define h_HTSPERBLOCK 512 /* Power of 2 */
+#define h_HTSHIFT 9 /* log base 2 of HTSPERBLOCK */
-/* size of the hold array for each host */
-#define h_maxSlots ((MAX_FILESERVER_THREAD+h_threadsPerSlot-1)>>h_threadsShift)
+struct Identity {
+ char valid; /* zero if UUID is unknown */
+ afsUUID uuid;
+};
-struct Identity
-{
- char valid; /* zero if UUID is unknown */
- afsUUID uuid;
+struct AddrPort {
+ afs_uint32 addr; /* in network byte order */
+ afs_uint16 port; /* in network byte order */
+ afs_int16 valid;
};
-struct Interface
-{
- int numberOfInterfaces;
- afsUUID uuid;
- afs_int32 addr[1]; /* there are actually more than one here */
- /* in network byte order */
+struct Interface {
+ afsUUID uuid;
+ int numberOfInterfaces;
+ struct AddrPort interface[1];/* there are actually more than one here */
+ /* in network byte order */
};
+
struct host {
- struct host *next, *prev; /* linked list of all hosts */
- struct rx_connection *callback_rxcon; /* rx callback connection */
- afs_int32 holds[h_maxSlots];
- /* holds on this host; 1 bit per lwp.
- A hold prevents this structure and
- inferior structures from disappearing */
- unsigned int host; /* IP address of host interface that is
- currently being used, in network
- byte order*/
- unsigned short port; /* port address of host */
- char Console; /* XXXX This host is a console */
- char hostFlags; /* bit map */
+ struct host *next, *prev; /* linked list of all hosts */
+ struct rx_connection *callback_rxcon; /* rx callback connection */
+ afs_uint32 refCount; /* reference count */
+ afs_uint32 host; /* IP address of host interface that is
+ * currently being used, in network
+ * byte order */
+ afs_uint16 port; /* port address of host */
+ char Console; /* XXXX This host is a console */
+ unsigned short hostFlags; /* bit map */
#if FS_STATS_DETAILED
- char InSameNetwork; /*Is host's addr in the same network as
- the File Server's?*/
- char dummy[3]; /* for padding */
-#endif /* FS_STATS_DETAILED */
- char hcpsfailed; /* Retry the cps call next time */
- prlist hcps; /* cps for hostip acls */
- afs_uint32 LastCall; /* time of last call from host */
- afs_uint32 ActiveCall; /* time of any call but gettime */
- struct client *FirstClient; /* first connection from host */
- afs_uint32 cpsCall; /* time of last cps call from this host */
- struct Interface* interface; /* all alternate addr for client */
- afs_uint32 cblist; /* Call back list for this host */
+ char InSameNetwork; /*Is host's addr in the same network as
+ * the File Server's? */
+ char dummy[3]; /* for padding */
+#endif /* FS_STATS_DETAILED */
+ char hcpsfailed; /* Retry the cps call next time */
+ prlist hcps; /* cps for hostip acls */
+ afs_uint32 LastCall; /* time of last call from host */
+ afs_uint32 ActiveCall; /* time of any call but gettime,
+ getstats and getcaps */
+ struct client *FirstClient; /* first connection from host */
+ afs_uint32 cpsCall; /* time of last cps call from this host */
+ struct Interface *interface; /* all alternate addr for client */
+ afs_uint32 cblist; /* index of a cb in the per-host circular CB list */
/*
* These don't get zeroed, keep them at the end. If index doesn't
* follow an unsigned short then we need to pad to ensure that
* the index fields isn't zeroed. XXX
*/
- afs_uint32 index; /* Host table index, for vicecb.c */
- struct Lock lock; /* Write lock for synchronization of
- VenusDown flag */
+ afs_uint32 index; /* Host table index, for vicecb.c */
+ struct Lock lock; /* Write lock for synchronization of
+ * VenusDown flag */
#ifdef AFS_PTHREAD_ENV
- pthread_cond_t cond; /* used to wait on hcpsValid */
-#endif /* AFS_PTHREAD_ENV */
+ pthread_cond_t cond; /* used to wait on hcpsValid */
+#endif /* AFS_PTHREAD_ENV */
};
/* * Don't zero the index, lock or condition varialbles */
#define HOST_TO_ZERO(H) (int)(((char *)(&((H)->index))-(char *)(H)))
-struct h_hashChain
-{
- struct host* hostPtr;
- struct h_hashChain* next;
- afs_int32 addr;
-};
+struct h_AddrHashChain {
+ struct host *hostPtr;
+ struct h_AddrHashChain *next;
+ afs_uint32 addr;
+ afs_uint16 port;
+};
+
+struct h_UuidHashChain {
+ struct host *hostPtr;
+ struct h_UuidHashChain *next;
+};
struct client {
- struct client *next; /* next client entry for host */
- struct host *host; /* ptr to parent host entry */
- afs_int32 sid; /* Connection number from this host */
- struct rx_connection *tcon; /* most recent server connection
- * associated with this client */
- prlist CPS; /* cps for authentication */
- int ViceId; /* Vice ID of user */
- afs_int32 expTime; /* RX-only: expiration time */
- afs_uint32 LastCall; /* time of last call */
- afs_uint32 VenusEpoch; /* Venus start time--used to identify
- * venus. Actually, now an extension of the
- * sid, which is why it moved.
- */
- afs_int32 refCount; /* reference count */
- char deleted; /* True if this client should be deleted
- when there are no more users of the
- structure */
- char authClass; /* auth type, RX-only */
- char prfail; /* True if prserver couldn't be contacted */
+ struct client *next; /* next client entry for host */
+ struct host *host; /* ptr to parent host entry */
+ afs_int32 sid; /* Connection number from this host */
+ prlist CPS; /* cps for authentication */
+ int ViceId; /* Vice ID of user */
+ afs_int32 expTime; /* RX-only: expiration time */
+ afs_uint32 LastCall; /* time of last call */
+ afs_uint32 VenusEpoch; /* Venus start time--used to identify
+ * venus. Actually, now an extension of the
+ * sid, which is why it moved.
+ */
+ afs_int32 refCount; /* reference count */
+ char deleted; /* True if this client should be deleted
+ * when there are no more users of the
+ * structure */
+ char authClass; /* auth type, RX-only */
+ char prfail; /* True if prserver couldn't be contacted */
#if FS_STATS_DETAILED
- char InSameNetwork; /* Is client's IP address in the same
- network as ours? */
-#else /* FS_STATS_DETAILED */
- char dummy; /* For padding */
-#endif /* FS_STATS_DETAILED */
- struct Lock lock; /* lock to ensure CPS valid if entry
- * on host's clients list. */
+ char InSameNetwork; /* Is client's IP address in the same
+ * network as ours? */
+#else /* FS_STATS_DETAILED */
+ char dummy; /* For padding */
+#endif /* FS_STATS_DETAILED */
+ struct Lock lock; /* lock to ensure CPS valid if entry
+ * on host's clients list. */
};
/* Don't zero the lock */
#define CLIENT_TO_ZERO(C) ((int)(((char *)(&((C)->lock))-(char *)(C))))
+
/*
* key for the client structure stored in connection specific data
*/
for the client, then the client must have a connection */
/* N.B. h_UserName returns pointer to static data; also relatively expensive */
extern char *h_UserName(struct client *client);
-
-/* all threads whose thread-id is greater than the size of the hold array,
-** then use the most significant bit in the 'hold' field in the host structure
-*/
-#ifdef AFS_PTHREAD_ENV
-#define h_lwpIndex() ( ((long)(pthread_getspecific(rx_thread_id_key)) > \
- ((h_maxSlots << h_threadsShift)-1)) ? \
- (h_maxSlots << h_threadsShift) -1 : \
- (long)(pthread_getspecific(rx_thread_id_key)) )
-#else /* AFS_PTHREAD_ENV */
-#define h_lwpIndex() ( (LWP_Index() > ((h_maxSlots << h_threadsShift)-1)) ? \
- (h_maxSlots << h_threadsShift) -1 : \
- LWP_Index() )
-#endif /* AFS_PTHREAD_ENV */
-#define h_holdIndex()( h_lwpIndex() & h_threadsMask)
-#define h_holdSlot() ( h_lwpIndex() >> h_threadsShift) /*index in 'holds'*/
-#define h_holdbit() ( 1<<h_holdIndex() )
-
-#define h_Hold_r(host) ((host)->holds[h_holdSlot()] |= h_holdbit())
-extern int h_Release(register struct host *host);
-extern int h_Release_r(register struct host *host);
-
-#define h_Held_r(host) ((h_holdbit() & (host)->holds[h_holdSlot()]) != 0)
-extern int h_OtherHolds_r(register struct host *host);
#define h_Lock(host) ObtainWriteLock(&(host)->lock)
-extern int h_Lock_r(register struct host *host);
+extern int h_Lock_r(struct host *host);
#define h_Unlock(host) ReleaseWriteLock(&(host)->lock)
#define h_Unlock_r(host) ReleaseWriteLock(&(host)->lock)
#define AddVolCallBack(host, fid) AddCallBack1((host), (fid), (afs_uint32 *)0, 3/*CB_VOLUME*/, 0)
#define AddBulkCallBack(host, fid) AddCallBack1((host), (fid), (afs_uint32 *)0, 4/*CB_BULK*/, 0)
+/* A simple refCount replaces per-thread hold mechanism. The former
+ * hold semantics are not different from refcounting, except with respect
+ * to cross-thread assertions. In this change, refcount is protected by
+ * H_LOCK, just like former hold bitmap. A future change will replace locks
+ * th lock-free operations. */
+
+#define h_Hold_r(x) \
+do { \
+ ++((x)->refCount); \
+} while(0)
+
+#define h_Decrement_r(x) \
+do { \
+ --((x)->refCount); \
+} while (0)
+
+#define h_Release_r(x) \
+do { \
+ h_Decrement_r(x); \
+ if (((x)->refCount < 1) && \
+ (((x)->hostFlags & HOSTDELETED) || \
+ ((x)->hostFlags & CLIENTDELETED))) h_TossStuff_r((x)); \
+} while(0)
+
/* operations on the global linked list of hosts */
#define h_InsertList_r(h) (h)->next = hostList; \
(h)->prev = 0; \
hostList ? (hostList->prev = (h)):0; \
hostList = (h); \
hostCount++;
-#define h_DeleteList_r(h) assert(hostCount>0); \
+#define h_DeleteList_r(h) osi_Assert(hostCount>0); \
hostCount--; \
(h)->next ? ((h)->next->prev = (h)->prev):0;\
(h)->prev ? ((h)->prev->next = (h)->next):0;\
( h == hostList )? (hostList = h->next):0;
-extern struct host *h_Alloc(register struct rx_connection *r_con);
-extern struct host *h_Alloc_r(register struct rx_connection *r_con);
-extern struct host *h_Lookup_r(afs_uint32 hostaddr, afs_uint32 hport, int *heldp);
-extern struct host *h_LookupUuid_r(afsUUID *uuidp);
-extern int h_FreeConnection(struct rx_connection *tcon);
-extern void h_Enumerate(int (*proc)(), char *param);
+extern int DeleteAllCallBacks_r(struct host *host, int deletefe);
+extern int DeleteCallBack(struct host *host, AFSFid * fid);
+extern int MultiProbeAlternateAddress_r(struct host *host);
+extern int BreakDelayedCallBacks_r(struct host *host);
+extern int AddCallBack1(struct host *host, AFSFid * fid, afs_uint32 * thead, int type,
+ int locked);
+extern int BreakCallBack(struct host *xhost, AFSFid * fid, int flag);
+extern int DeleteFileCallBacks(AFSFid * fid);
+extern int CleanupTimedOutCallBacks(void);
+extern int CleanupTimedOutCallBacks_r(void);
+extern int MultiBreakCallBackAlternateAddress(struct host *host, struct AFSCBFids *afidp);
+extern int MultiBreakCallBackAlternateAddress_r(struct host *host,
+ struct AFSCBFids *afidp);
+extern int DumpCallBackState(void);
+extern int PrintCallBackStats(void);
+extern void *ShutDown(void *);
+extern void ShutDownAndCore(int dopanic);
+
+extern int h_Lookup_r(afs_uint32 hostaddr, afs_uint16 hport,
+ struct host **hostp);
+extern struct host *h_LookupUuid_r(afsUUID * uuidp);
+extern void h_Enumerate(int (*proc) (struct host *, void *), void *param);
+extern void h_Enumerate_r(int (*proc) (struct host *, void *), struct host *enumstart, void *param);
extern struct host *h_GetHost_r(struct rx_connection *tcon);
extern struct client *h_FindClient_r(struct rx_connection *tcon);
extern int h_ReleaseClient_r(struct client *client);
+extern void h_TossStuff_r(struct host *host);
extern struct client *h_ID2Client(afs_int32 vid);
-extern int GetClient(struct rx_connection * tcon, struct client **cp);
-extern void h_PrintStats();
-extern void h_PrintClients();
-extern void h_GetWorkStats();
-extern void h_flushhostcps(register afs_uint32 hostaddr, register afs_uint32 hport);
-struct Interface *MultiVerifyInterface_r();
-
-struct host *(hosttableptrs[h_MAXHOSTTABLES]); /* Used by h_itoh */
-#define h_htoi(host) ((host)->index) /* index isn't zeroed, no need to lock */
+extern int GetClient(struct rx_connection *tcon, struct client **cp);
+extern int PutClient(struct client **cp);
+extern void h_PrintStats(void);
+extern void h_PrintClients(void);
+extern void h_GetWorkStats(int *, int *, int *, afs_int32);
+extern void h_GetWorkStats64(afs_uint64 *, afs_uint64 *, afs_uint64 *, afs_int32);
+extern void h_flushhostcps(afs_uint32 hostaddr,
+ afs_uint16 hport);
+extern void h_GetHostNetStats(afs_int32 * a_numHostsP, afs_int32 * a_sameNetOrSubnetP,
+ afs_int32 * a_diffSubnetP, afs_int32 * a_diffNetworkP);
+extern int h_NBLock_r(struct host *host);
+extern void h_DumpHosts(void);
+extern void h_InitHostPackage(void);
+extern void h_CheckHosts(void );
+extern int initInterfaceAddr_r(struct host *host, struct interfaceAddr *interf);
+extern void h_AddHostToAddrHashTable_r(afs_uint32 addr, afs_uint16 port, struct host * host);
+extern void h_AddHostToUuidHashTable_r(afsUUID * uuid, struct host * host);
+extern int h_DeleteHostFromAddrHashTable_r(afs_uint32 addr, afs_uint16 port, struct host *host);
+extern int h_DeleteHostFromUuidHashTable_r(struct host *host);
+extern int initInterfaceAddr_r(struct host *host, struct interfaceAddr *interf);
+extern int addInterfaceAddr_r(struct host *host, afs_uint32 addr, afs_uint16 port);
+extern int removeInterfaceAddr_r(struct host *host, afs_uint32 addr, afs_uint16 port);
+extern afs_int32 hpr_Initialize(struct ubik_client **);
+extern int hpr_End(struct ubik_client *);
+extern int hpr_IdToName(idlist *ids, namelist *names);
+extern int hpr_NameToId(namelist *names, idlist *ids);
+
+#ifdef AFS_DEMAND_ATTACH_FS
+/*
+ * demand attach fs
+ * state serialization
+ */
+extern int h_SaveState(void);
+extern int h_RestoreState(void);
+#endif
+
+#define H_ENUMERATE_BAIL(flags) ((flags)|0x80000000)
+#define H_ENUMERATE_ISSET_BAIL(flags) ((flags)&0x80000000)
+
+struct host *(hosttableptrs[h_MAXHOSTTABLES]); /* Used by h_itoh */
+#define h_htoi(host) ((host)->index) /* index isn't zeroed, no need to lock */
#define h_itoh(hostindex) (hosttableptrs[(hostindex)>>h_HTSHIFT]+((hostindex)&(h_HTSPERBLOCK-1)))
-#define HCPS_INPROGRESS 0x01 /*set when CPS is being updated */
-#define HCPS_WAITING 0x02 /*waiting for CPS to get updated*/
-#define ALTADDR 0x04 /*InitCallBack is being done */
-#define VENUSDOWN 0x08 /* venus CallBack failed */
-#define HOSTDELETED 0x10 /* host delated */
-#define CLIENTDELETED 0x20 /* client deleted */
-#define RESETDONE 0x40 /* callback reset done */
-#define HFE_LATER 0x80 /* host has FE_LATER callbacks */
+#define rxr_GetEpoch(aconn) (((struct rx_connection *)(aconn))->epoch)
+
+#define rxr_CidOf(aconn) (((struct rx_connection *)(aconn))->cid)
+
+#define rxr_PortOf(aconn) \
+ rx_PortOf(rx_PeerOf(((struct rx_connection *)(aconn))))
+
+#define rxr_HostOf(aconn) \
+ rx_HostOf(rx_PeerOf((struct rx_connection *)(aconn)))
+
+#define HCPS_INPROGRESS 0x01 /*set when CPS is being updated */
+#define HCPS_WAITING 0x02 /*waiting for CPS to get updated */
+#define ALTADDR 0x04 /*InitCallBack is being done */
+#define VENUSDOWN 0x08 /* venus CallBack failed */
+#define HOSTDELETED 0x10 /* host delated */
+#define CLIENTDELETED 0x20 /* client deleted */
+#define RESETDONE 0x40 /* callback reset done */
+#define HFE_LATER 0x80 /* host has FE_LATER callbacks */
+#define HERRORTRANS 0x100 /* do error translation */
+#define HWHO_INPROGRESS 0x200 /* set when WhoAreYou running */
+#define HCBREAK 0x400 /* flag for a multi CB break */
+#endif /* _AFS_VICED_HOST_H */