viced-avoid-tying-up-all-threads-20070730
[openafs.git] / src / viced / host.h
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  *
9  * Portions Copyright (c) 2006 Sine Nomine Associates
10  */
11
12 #ifndef _AFS_VICED_HOST_H
13 #define _AFS_VICED_HOST_H
14
15 #include "fs_stats.h"           /*File Server stats package */
16
17 #ifdef AFS_PTHREAD_ENV
18 /*
19  * There are three locks in the host package.
20  * the global hash lock protects hash chains.
21  * the global list lock protects the list of hosts.
22  * a mutex in each host structure protects the structure.
23  * precedence is host_listlock_mutex, host->mutex, host_glock_mutex.
24  */
25 #include <rx/rx_globals.h>
26 #include <assert.h>
27 #include <pthread.h>
28 extern pthread_mutex_t host_glock_mutex;
29 #define H_LOCK \
30     assert(pthread_mutex_lock(&host_glock_mutex) == 0)
31 #define H_UNLOCK \
32     assert(pthread_mutex_unlock(&host_glock_mutex) == 0)
33 extern pthread_key_t viced_uclient_key;
34 #else /* AFS_PTHREAD_ENV */
35 #define H_LOCK
36 #define H_UNLOCK
37 #endif /* AFS_PTHREAD_ENV */
38
39 #define h_MAXHOSTTABLEENTRIES 1000
40 #define h_HASHENTRIES 256       /* Power of 2 */
41 #define h_MAXHOSTTABLES 200
42 #define h_HTSPERBLOCK 512       /* Power of 2 */
43 #define h_HTSHIFT 9             /* log base 2 of HTSPERBLOCK */
44
45 #define h_threadsPerSlot        32      /* bits per afs_int32 */
46 #define h_threadsShift          5       /* for multiply/divide */
47 #define h_threadsMask           31      /* for remainder */
48
49 /* size of the hold array for each host */
50 #define h_maxSlots      (((MAX_FILESERVER_THREAD+h_threadsPerSlot-1)>>h_threadsShift)+1)
51
52 struct Identity {
53     char valid;                 /* zero if UUID is unknown */
54     afsUUID uuid;
55 };
56
57 struct AddrPort  {
58     afs_uint32 addr;            /* in network byte order */
59     afs_uint16 port;            /* in network byte order */
60 };
61
62 struct Interface {
63     afsUUID uuid;
64     int numberOfInterfaces;
65     struct AddrPort interface[1];/* there are actually more than one here */
66     /* in network byte order */
67 };
68
69 struct host {
70     struct host *next, *prev;   /* linked list of all hosts */
71     struct rx_connection *callback_rxcon;       /* rx callback connection */
72     afs_int32 holds[h_maxSlots];
73     /* holds on this host; 1 bit per lwp.
74      * A hold prevents this structure and
75      * inferior structures from disappearing */
76     afs_uint32 host;            /* IP address of host interface that is
77                                  * currently being used, in network
78                                  * byte order */
79     afs_uint16 port;            /* port address of host */
80     char Console;               /* XXXX This host is a console */
81     unsigned short hostFlags;           /*  bit map */
82 #if FS_STATS_DETAILED
83     char InSameNetwork;         /*Is host's addr in the same network as
84                                  * the File Server's? */
85     char dummy[3];              /* for padding */
86 #endif                          /* FS_STATS_DETAILED */
87     char hcpsfailed;            /* Retry the cps call next time */
88     prlist hcps;                /* cps for hostip acls */
89     afs_uint32 LastCall;        /* time of last call from host */
90     afs_uint32 ActiveCall;      /* time of any call but gettime, 
91                                    getstats and getcaps */
92     struct client *FirstClient; /* first connection from host */
93     afs_uint32 cpsCall;         /* time of last cps call from this host */
94     struct Interface *interface;        /* all alternate addr for client */
95     afs_uint32 cblist;          /* index of a cb in the per-host circular CB list */
96     /*
97      * These don't get zeroed, keep them at the end. If index doesn't
98      * follow an unsigned short then we need to pad to ensure that
99      * the index fields isn't zeroed. XXX
100      */
101     afs_uint32 index;           /* Host table index, for vicecb.c */
102     struct Lock lock;           /* Write lock for synchronization of
103                                  * VenusDown flag */
104 #ifdef AFS_PTHREAD_ENV
105     pthread_cond_t cond;        /* used to wait on hcpsValid */
106 #endif                          /* AFS_PTHREAD_ENV */
107 };
108
109 /* * Don't zero the index, lock or condition varialbles */
110 #define HOST_TO_ZERO(H) (int)(((char *)(&((H)->index))-(char *)(H)))
111
112 struct h_hashChain {
113     struct host *hostPtr;
114     struct h_hashChain *next;
115     afs_uint32 addr;
116     afs_uint16 port;
117 };
118
119 struct client {
120     struct client *next;        /* next client entry for host */
121     struct host *host;          /* ptr to parent host entry */
122     afs_int32 sid;              /* Connection number from this host */
123     prlist CPS;                 /* cps for authentication */
124     int ViceId;                 /* Vice ID of user */
125     afs_int32 expTime;          /* RX-only: expiration time */
126     afs_uint32 LastCall;        /* time of last call */
127     afs_uint32 VenusEpoch;      /* Venus start time--used to identify
128                                  * venus.  Actually, now an extension of the
129                                  * sid, which is why it moved.
130                                  */
131     afs_int32 refCount;         /* reference count */
132     char deleted;               /* True if this client should be deleted
133                                  * when there are no more users of the
134                                  * structure */
135     char authClass;             /* auth type, RX-only */
136     char prfail;                /* True if prserver couldn't be contacted */
137 #if FS_STATS_DETAILED
138     char InSameNetwork;         /* Is client's IP address in the same
139                                  * network as ours? */
140 #else                           /* FS_STATS_DETAILED */
141     char dummy;                 /* For padding */
142 #endif                          /* FS_STATS_DETAILED */
143     struct Lock lock;           /* lock to ensure CPS valid if entry
144                                  * on host's clients list. */
145 };
146
147 /* Don't zero the lock */
148 #define CLIENT_TO_ZERO(C)       ((int)(((char *)(&((C)->lock))-(char *)(C))))
149
150
151 /*
152  * key for the client structure stored in connection specific data
153  */
154 extern int rxcon_client_key;
155
156 /* Some additional functions to get at client information.  Client must have
157    an active connection for this to work.  If a lwp is working on a request
158    for the client, then the client must have a connection */
159 /* N.B. h_UserName returns pointer to static data; also relatively expensive */
160 extern char *h_UserName(struct client *client);
161
162 /* all threads whose thread-id is greater than the size of the hold array,
163 ** then use the most significant bit in the 'hold' field in the host structure 
164 */
165 #ifdef AFS_PTHREAD_ENV
166 #define h_lwpIndex() ( ((long)(pthread_getspecific(rx_thread_id_key)) > \
167                         ((h_maxSlots << h_threadsShift)-1)) ? \
168                                 (h_maxSlots << h_threadsShift) -1 : \
169                                 (long)(pthread_getspecific(rx_thread_id_key)) )
170 #else /* AFS_PTHREAD_ENV */
171 #define h_lwpIndex() ( (LWP_Index() > ((h_maxSlots << h_threadsShift)-1)) ? \
172                                         (h_maxSlots << h_threadsShift) -1 : \
173                                         LWP_Index() )
174 #endif /* AFS_PTHREAD_ENV */
175 #define h_holdIndex()( h_lwpIndex() & h_threadsMask)
176 #define h_holdSlot() ( h_lwpIndex() >> h_threadsShift)  /*index in 'holds' */
177 #define h_holdbit()  ( 1<<h_holdIndex() )
178
179 #define h_Hold_r(host)   ((host)->holds[h_holdSlot()] |= h_holdbit())
180 extern int h_Release(register struct host *host);
181 extern int h_Release_r(register struct host *host);
182
183 #define h_Held_r(host)   ((h_holdbit() & (host)->holds[h_holdSlot()]) != 0)
184 extern int h_OtherHolds_r(register struct host *host);
185 #define h_Lock(host)    ObtainWriteLock(&(host)->lock)
186 extern int h_Lock_r(register struct host *host);
187 #define h_Unlock(host)  ReleaseWriteLock(&(host)->lock)
188 #define h_Unlock_r(host)  ReleaseWriteLock(&(host)->lock)
189
190 #define AddCallBack(host, fid)  AddCallBack1((host), (fid), (afs_uint32 *)0, 1/*CB_NORMAL*/, 0)
191 #define AddVolCallBack(host, fid) AddCallBack1((host), (fid), (afs_uint32 *)0, 3/*CB_VOLUME*/, 0)
192 #define AddBulkCallBack(host, fid) AddCallBack1((host), (fid), (afs_uint32 *)0, 4/*CB_BULK*/, 0)
193
194 /* operations on the global linked list of hosts */
195 #define h_InsertList_r(h)       (h)->next =  hostList;                  \
196                                 (h)->prev = 0;                          \
197                                 hostList ? (hostList->prev = (h)):0;    \
198                                 hostList = (h);                         \
199                                 hostCount++;
200 #define h_DeleteList_r(h)       assert(hostCount>0);                        \
201                                 hostCount--;                                \
202                                 (h)->next ? ((h)->next->prev = (h)->prev):0;\
203                                 (h)->prev ? ((h)->prev->next = (h)->next):0;\
204                                 ( h == hostList )? (hostList = h->next):0;
205
206 extern int DeleteAllCallBacks_r(struct host *host, int deletefe);
207 extern int DeleteCallBack(struct host *host, AFSFid * fid);
208 extern int MultiProbeAlternateAddress_r(struct host *host);
209 extern int BreakDelayedCallBacks_r(struct host *host);
210 extern int AddCallBack1(struct host *host, AFSFid * fid, afs_uint32 * thead, int type,
211              int locked);
212 extern int BreakCallBack(struct host *xhost, AFSFid * fid, int flag);
213 extern int DeleteFileCallBacks(AFSFid * fid);
214 extern int CleanupTimedOutCallBacks(void);
215 extern int CleanupTimedOutCallBacks_r(void);
216 extern int MultiBreakCallBackAlternateAddress(struct host *host, struct AFSCBFids *afidp);
217 extern int MultiBreakCallBackAlternateAddress_r(struct host *host,
218                                      struct AFSCBFids *afidp);
219 extern int DumpCallBackState(void);
220 extern int PrintCallBackStats(void);
221 extern int ShutDown(void);
222 extern void ShutDownAndCore(int dopanic);
223
224 extern struct host *h_Alloc(register struct rx_connection *r_con);
225 extern struct host *h_Alloc_r(register struct rx_connection *r_con);
226 extern struct host *h_Lookup_r(afs_uint32 hostaddr, afs_uint16 hport,
227                                int *heldp);
228 extern void   hashInsert_r(afs_uint32 addr, afs_uint16 port, 
229                            struct host* host);
230 extern struct host *h_LookupUuid_r(afsUUID * uuidp);
231 extern void h_Enumerate(int (*proc) (), char *param);
232 extern void h_Enumerate_r(int (*proc) (), struct host *enumstart, char *param);
233 extern struct host *h_GetHost_r(struct rx_connection *tcon);
234 extern struct client *h_FindClient_r(struct rx_connection *tcon);
235 extern int h_ReleaseClient_r(struct client *client);
236 extern struct client *h_ID2Client(afs_int32 vid);
237 extern int GetClient(struct rx_connection *tcon, struct client **cp);
238 extern int PutClient(struct client **cp);
239 extern void h_PrintStats();
240 extern void h_PrintClients();
241 extern void h_GetWorkStats();
242 extern void h_flushhostcps(register afs_uint32 hostaddr,
243                            register afs_uint16 hport);
244 extern void h_GetHostNetStats(afs_int32 * a_numHostsP, afs_int32 * a_sameNetOrSubnetP,
245                   afs_int32 * a_diffSubnetP, afs_int32 * a_diffNetworkP);
246 extern int h_NBLock_r(register struct host *host);
247 extern void h_DumpHosts();
248 extern void h_InitHostPackage();
249 extern void h_CheckHosts();
250 struct Interface *MultiVerifyInterface_r();
251 extern int initInterfaceAddr_r(struct host *host, struct interfaceAddr *interf);
252
253 #ifdef AFS_DEMAND_ATTACH_FS
254 /*
255  * demand attach fs
256  * state serialization
257  */
258 extern int h_SaveState(void);
259 extern int h_RestoreState(void);
260 #endif
261
262 #define H_ENUMERATE_BAIL(held)        ((held)|0x80000000)
263 #define H_ENUMERATE_ISSET_BAIL(held)  ((held)&0x80000000)
264 #define H_ENUMERATE_ISSET_HELD(held)  ((held)&0x7FFFFFFF)
265
266 struct host *(hosttableptrs[h_MAXHOSTTABLES]);  /* Used by h_itoh */
267 #define h_htoi(host) ((host)->index)    /* index isn't zeroed, no need to lock */
268 #define h_itoh(hostindex) (hosttableptrs[(hostindex)>>h_HTSHIFT]+((hostindex)&(h_HTSPERBLOCK-1)))
269
270 #define rxr_GetEpoch(aconn) (((struct rx_connection *)(aconn))->epoch)
271
272 #define rxr_CidOf(aconn) (((struct rx_connection *)(aconn))->cid)
273
274 #define rxr_PortOf(aconn) \
275     rx_PortOf(rx_PeerOf(((struct rx_connection *)(aconn))))
276
277 #define rxr_HostOf(aconn) \
278     rx_HostOf(rx_PeerOf((struct rx_connection *)(aconn)))
279
280 #define HCPS_INPROGRESS                 0x01    /*set when CPS is being updated */
281 #define HCPS_WAITING                    0x02    /*waiting for CPS to get updated */
282 #define ALTADDR                         0x04    /*InitCallBack is being done */
283 #define VENUSDOWN                       0x08    /* venus CallBack failed */
284 #define HOSTDELETED                     0x10    /* host delated */
285 #define CLIENTDELETED                   0x20    /* client deleted */
286 #define RESETDONE                       0x40    /* callback reset done */
287 #define HFE_LATER                       0x80    /* host has FE_LATER callbacks */
288 #define HERRORTRANS                    0x100    /* do error translation */
289 #define HWHO_INPROGRESS                0x200    /* set when WhoAreYou running */
290 #endif /* _AFS_VICED_HOST_H */