932e3c48b2f38f2b94cc38dc2862bdb10fc8ef1e
[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     afs_int16  valid;
61 };
62
63 struct Interface {
64     afsUUID uuid;
65     int numberOfInterfaces;
66     struct AddrPort interface[1];/* there are actually more than one here */
67     /* in network byte order */
68 };
69
70 struct host {
71     struct host *next, *prev;   /* linked list of all hosts */
72     struct rx_connection *callback_rxcon;       /* rx callback connection */
73     afs_int32 holds[h_maxSlots];
74     /* holds on this host; 1 bit per lwp.
75      * A hold prevents this structure and
76      * inferior structures from disappearing */
77     afs_uint32 host;            /* IP address of host interface that is
78                                  * currently being used, in network
79                                  * byte order */
80     afs_uint16 port;            /* port address of host */
81     char Console;               /* XXXX This host is a console */
82     unsigned short hostFlags;           /*  bit map */
83 #if FS_STATS_DETAILED
84     char InSameNetwork;         /*Is host's addr in the same network as
85                                  * the File Server's? */
86     char dummy[3];              /* for padding */
87 #endif                          /* FS_STATS_DETAILED */
88     char hcpsfailed;            /* Retry the cps call next time */
89     prlist hcps;                /* cps for hostip acls */
90     afs_uint32 LastCall;        /* time of last call from host */
91     afs_uint32 ActiveCall;      /* time of any call but gettime, 
92                                    getstats and getcaps */
93     struct client *FirstClient; /* first connection from host */
94     afs_uint32 cpsCall;         /* time of last cps call from this host */
95     struct Interface *interface;        /* all alternate addr for client */
96     afs_uint32 cblist;          /* index of a cb in the per-host circular CB list */
97     /*
98      * These don't get zeroed, keep them at the end. If index doesn't
99      * follow an unsigned short then we need to pad to ensure that
100      * the index fields isn't zeroed. XXX
101      */
102     afs_uint32 index;           /* Host table index, for vicecb.c */
103     struct Lock lock;           /* Write lock for synchronization of
104                                  * VenusDown flag */
105 #ifdef AFS_PTHREAD_ENV
106     pthread_cond_t cond;        /* used to wait on hcpsValid */
107 #endif                          /* AFS_PTHREAD_ENV */
108 };
109
110 /* * Don't zero the index, lock or condition varialbles */
111 #define HOST_TO_ZERO(H) (int)(((char *)(&((H)->index))-(char *)(H)))
112
113 struct h_AddrHashChain {
114     struct host *hostPtr;
115     struct h_AddrHashChain *next;
116     afs_uint32 addr;
117     afs_uint16 port;
118 };
119
120 struct h_UuidHashChain {
121     struct host *hostPtr;
122     struct h_UuidHashChain *next;
123 };
124
125 struct client {
126     struct client *next;        /* next client entry for host */
127     struct host *host;          /* ptr to parent host entry */
128     afs_int32 sid;              /* Connection number from this host */
129     prlist CPS;                 /* cps for authentication */
130     int ViceId;                 /* Vice ID of user */
131     afs_int32 expTime;          /* RX-only: expiration time */
132     afs_uint32 LastCall;        /* time of last call */
133     afs_uint32 VenusEpoch;      /* Venus start time--used to identify
134                                  * venus.  Actually, now an extension of the
135                                  * sid, which is why it moved.
136                                  */
137     afs_int32 refCount;         /* reference count */
138     char deleted;               /* True if this client should be deleted
139                                  * when there are no more users of the
140                                  * structure */
141     char authClass;             /* auth type, RX-only */
142     char prfail;                /* True if prserver couldn't be contacted */
143 #if FS_STATS_DETAILED
144     char InSameNetwork;         /* Is client's IP address in the same
145                                  * network as ours? */
146 #else                           /* FS_STATS_DETAILED */
147     char dummy;                 /* For padding */
148 #endif                          /* FS_STATS_DETAILED */
149     struct Lock lock;           /* lock to ensure CPS valid if entry
150                                  * on host's clients list. */
151 };
152
153 /* Don't zero the lock */
154 #define CLIENT_TO_ZERO(C)       ((int)(((char *)(&((C)->lock))-(char *)(C))))
155
156
157 /*
158  * key for the client structure stored in connection specific data
159  */
160 extern int rxcon_client_key;
161
162 /* Some additional functions to get at client information.  Client must have
163    an active connection for this to work.  If a lwp is working on a request
164    for the client, then the client must have a connection */
165 /* N.B. h_UserName returns pointer to static data; also relatively expensive */
166 extern char *h_UserName(struct client *client);
167
168 /* all threads whose thread-id is greater than the size of the hold array,
169 ** then use the most significant bit in the 'hold' field in the host structure 
170 */
171 #ifdef AFS_PTHREAD_ENV
172 #define h_lwpIndex() ( ((long)(pthread_getspecific(rx_thread_id_key)) > \
173                         ((h_maxSlots << h_threadsShift)-1)) ? \
174                                 (h_maxSlots << h_threadsShift) -1 : \
175                                 (long)(pthread_getspecific(rx_thread_id_key)) )
176 #else /* AFS_PTHREAD_ENV */
177 #define h_lwpIndex() ( (LWP_Index() > ((h_maxSlots << h_threadsShift)-1)) ? \
178                                         (h_maxSlots << h_threadsShift) -1 : \
179                                         LWP_Index() )
180 #endif /* AFS_PTHREAD_ENV */
181 #define h_holdIndex()( h_lwpIndex() & h_threadsMask)
182 #define h_holdSlot() ( h_lwpIndex() >> h_threadsShift)  /*index in 'holds' */
183 #define h_holdbit()  ( 1<<h_holdIndex() )
184
185 #define h_Hold_r(host)   ((host)->holds[h_holdSlot()] |= h_holdbit())
186 extern int h_Release(register struct host *host);
187 extern int h_Release_r(register struct host *host);
188
189 #define h_Held_r(host)   ((h_holdbit() & (host)->holds[h_holdSlot()]) != 0)
190 extern int h_OtherHolds_r(register struct host *host);
191 #define h_Lock(host)    ObtainWriteLock(&(host)->lock)
192 extern int h_Lock_r(register struct host *host);
193 #define h_Unlock(host)  ReleaseWriteLock(&(host)->lock)
194 #define h_Unlock_r(host)  ReleaseWriteLock(&(host)->lock)
195
196 #define AddCallBack(host, fid)  AddCallBack1((host), (fid), (afs_uint32 *)0, 1/*CB_NORMAL*/, 0)
197 #define AddVolCallBack(host, fid) AddCallBack1((host), (fid), (afs_uint32 *)0, 3/*CB_VOLUME*/, 0)
198 #define AddBulkCallBack(host, fid) AddCallBack1((host), (fid), (afs_uint32 *)0, 4/*CB_BULK*/, 0)
199
200 /* operations on the global linked list of hosts */
201 #define h_InsertList_r(h)       (h)->next =  hostList;                  \
202                                 (h)->prev = 0;                          \
203                                 hostList ? (hostList->prev = (h)):0;    \
204                                 hostList = (h);                         \
205                                 hostCount++;
206 #define h_DeleteList_r(h)       assert(hostCount>0);                        \
207                                 hostCount--;                                \
208                                 (h)->next ? ((h)->next->prev = (h)->prev):0;\
209                                 (h)->prev ? ((h)->prev->next = (h)->next):0;\
210                                 ( h == hostList )? (hostList = h->next):0;
211
212 extern int DeleteAllCallBacks_r(struct host *host, int deletefe);
213 extern int DeleteCallBack(struct host *host, AFSFid * fid);
214 extern int MultiProbeAlternateAddress_r(struct host *host);
215 extern int BreakDelayedCallBacks_r(struct host *host);
216 extern int AddCallBack1(struct host *host, AFSFid * fid, afs_uint32 * thead, int type,
217              int locked);
218 extern int BreakCallBack(struct host *xhost, AFSFid * fid, int flag);
219 extern int DeleteFileCallBacks(AFSFid * fid);
220 extern int CleanupTimedOutCallBacks(void);
221 extern int CleanupTimedOutCallBacks_r(void);
222 extern int MultiBreakCallBackAlternateAddress(struct host *host, struct AFSCBFids *afidp);
223 extern int MultiBreakCallBackAlternateAddress_r(struct host *host,
224                                      struct AFSCBFids *afidp);
225 extern int DumpCallBackState(void);
226 extern int PrintCallBackStats(void);
227 extern void *ShutDown(void *);
228 extern void ShutDownAndCore(int dopanic);
229
230 extern struct host *h_Alloc(register struct rx_connection *r_con);
231 extern struct host *h_Alloc_r(register struct rx_connection *r_con);
232 extern int h_Lookup_r(afs_uint32 hostaddr, afs_uint16 hport,
233                       int *heldp, struct host **hostp);
234 extern struct host *h_LookupUuid_r(afsUUID * uuidp);
235 extern void h_Enumerate(int (*proc) (struct host *, int, void *), void *param);
236 extern void h_Enumerate_r(int (*proc) (struct host *, int, void *), struct host *enumstart, void *param);
237 extern struct host *h_GetHost_r(struct rx_connection *tcon);
238 extern struct client *h_FindClient_r(struct rx_connection *tcon);
239 extern int h_ReleaseClient_r(struct client *client);
240 extern struct client *h_ID2Client(afs_int32 vid);
241 extern int GetClient(struct rx_connection *tcon, struct client **cp);
242 extern int PutClient(struct client **cp);
243 extern void h_PrintStats(void);
244 extern void h_PrintClients(void);
245 extern void h_GetWorkStats(int *, int *, int *, afs_int32);
246 extern void h_flushhostcps(register afs_uint32 hostaddr,
247                            register afs_uint16 hport);
248 extern void h_GetHostNetStats(afs_int32 * a_numHostsP, afs_int32 * a_sameNetOrSubnetP,
249                   afs_int32 * a_diffSubnetP, afs_int32 * a_diffNetworkP);
250 extern int h_NBLock_r(register struct host *host);
251 extern void h_DumpHosts(void);
252 extern void h_InitHostPackage(void);
253 extern void h_CheckHosts(void );
254 extern int initInterfaceAddr_r(struct host *host, struct interfaceAddr *interf);
255 extern void h_AddHostToAddrHashTable_r(afs_uint32 addr, afs_uint16 port, struct host * host);
256 extern void h_AddHostToUuidHashTable_r(afsUUID * uuid, struct host * host);
257 extern int h_DeleteHostFromAddrHashTable_r(afs_uint32 addr, afs_uint16 port, struct host *host);
258 extern int h_DeleteHostFromUuidHashTable_r(struct host *host);
259 extern int initInterfaceAddr_r(struct host *host, struct interfaceAddr *interf);
260 extern int addInterfaceAddr_r(struct host *host, afs_uint32 addr, afs_uint16 port);
261 extern int removeInterfaceAddr_r(struct host *host, afs_uint32 addr, afs_uint16 port);
262 extern afs_int32 hpr_Initialize(struct ubik_client **);
263 extern int hpr_End(struct ubik_client *);
264
265
266 #ifdef AFS_DEMAND_ATTACH_FS
267 /*
268  * demand attach fs
269  * state serialization
270  */
271 extern int h_SaveState(void);
272 extern int h_RestoreState(void);
273 #endif
274
275 #define H_ENUMERATE_BAIL(held)        ((held)|0x80000000)
276 #define H_ENUMERATE_ISSET_BAIL(held)  ((held)&0x80000000)
277 #define H_ENUMERATE_ISSET_HELD(held)  ((held)&0x7FFFFFFF)
278
279 struct host *(hosttableptrs[h_MAXHOSTTABLES]);  /* Used by h_itoh */
280 #define h_htoi(host) ((host)->index)    /* index isn't zeroed, no need to lock */
281 #define h_itoh(hostindex) (hosttableptrs[(hostindex)>>h_HTSHIFT]+((hostindex)&(h_HTSPERBLOCK-1)))
282
283 #define rxr_GetEpoch(aconn) (((struct rx_connection *)(aconn))->epoch)
284
285 #define rxr_CidOf(aconn) (((struct rx_connection *)(aconn))->cid)
286
287 #define rxr_PortOf(aconn) \
288     rx_PortOf(rx_PeerOf(((struct rx_connection *)(aconn))))
289
290 #define rxr_HostOf(aconn) \
291     rx_HostOf(rx_PeerOf((struct rx_connection *)(aconn)))
292
293 #define HCPS_INPROGRESS                 0x01    /*set when CPS is being updated */
294 #define HCPS_WAITING                    0x02    /*waiting for CPS to get updated */
295 #define ALTADDR                         0x04    /*InitCallBack is being done */
296 #define VENUSDOWN                       0x08    /* venus CallBack failed */
297 #define HOSTDELETED                     0x10    /* host delated */
298 #define CLIENTDELETED                   0x20    /* client deleted */
299 #define RESETDONE                       0x40    /* callback reset done */
300 #define HFE_LATER                       0x80    /* host has FE_LATER callbacks */
301 #define HERRORTRANS                    0x100    /* do error translation */
302 #define HWHO_INPROGRESS                0x200    /* set when WhoAreYou running */
303 #endif /* _AFS_VICED_HOST_H */