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