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