Initial IBM OpenAFS 1.0 tree
[openafs.git] / src / afs / afs_util.c
1 /* Copyright (C) 1995, 1989, 1998 Transarc Corporation - All rights reserved */
2 /*
3  * (C) COPYRIGHT IBM CORPORATION 1987, 1988
4  * LICENSED MATERIALS - PROPERTY OF IBM
5  */
6 /*
7  * afs_util.c - miscellaneous AFS client utility functions
8  *
9  * Implements:
10  */
11 #include "../afs/param.h"       /* Should be always first */
12 #include "../afs/stds.h"
13 #include "../afs/sysincludes.h" /* Standard vendor system headers */
14
15 #if !defined(UKERNEL)
16 #include <net/if.h>
17 #include <netinet/in.h>
18
19 #ifdef AFS_SGI62_ENV
20 #include "../h/hashing.h"
21 #endif
22 #if !defined(AFS_HPUX110_ENV) && !defined(AFS_LINUX20_ENV)
23 #include <netinet/in_var.h>
24 #endif /* ! AFS_HPUX110_ENV */
25 #endif /* !defined(UKERNEL) */
26
27 #include "../afs/afsincludes.h" /* Afs-based standard headers */
28 #include "../afs/afs_stats.h"   /* afs statistics */
29
30 #if     defined(AFS_SUN56_ENV)
31 #include <inet/led.h>
32 #include <inet/common.h>
33 #include <inet/ip.h>
34 #endif
35
36 #if     defined(AFS_AIX_ENV)
37 #include <sys/fp_io.h>
38 #endif
39
40 extern struct volume *afs_volumes[NVOLS];
41
42 char *afs_cv2string(char *ttp, afs_uint32 aval)
43 {
44     register char *tp = ttp;
45     register int  i;
46     int any;
47     
48     AFS_STATCNT(afs_cv2string);
49     any = 0;
50     *(--tp) = 0;
51     while (aval != 0) {
52         i = aval % 10;
53         *(--tp) = '0' + i;
54         aval /= 10;
55         any = 1;
56     }
57     if (!any)
58         *(--tp) = '0';
59     return tp;
60
61 } /*afs_cv2string*/
62
63 void print_internet_address(char *preamble, struct srvAddr *sa,
64                             char *postamble, int flag)
65 {
66     register struct server *aserver = sa->server;
67     char *ptr = "\n";
68     afs_uint32 address;
69     
70     AFS_STATCNT(print_internet_address);
71     address = ntohl(sa->sa_ip);
72     if (aserver->flags & SRVR_MULTIHOMED) {
73         if (flag == 1) {        /* server down mesg */
74             if (!(aserver->flags & SRVR_ISDOWN))
75                 ptr = " (multi-homed address; other same-host interfaces maybe up)\n";
76             else
77                 ptr = " (all multi-homed ip addresses down for the server)\n";
78         } else if (flag == 2) { /* server up mesg */
79             ptr = " (multi-homed address; other same-host interfaces may still be down)\n";
80         }
81     }
82     afs_warn("%s%d.%d.%d.%d in cell %s%s%s",
83            preamble, (address >> 24), (address >> 16) & 0xff, (address >> 8) & 0xff, (address) & 0xff,
84            aserver->cell->cellName, postamble, ptr);
85     afs_warnuser("%s%d.%d.%d.%d in cell %s%s%s",
86             preamble, (address >> 24), (address >> 16) & 0xff, (address >> 8) & 0xff, (address) & 0xff,
87             aserver->cell->cellName, postamble, ptr);
88
89 } /*print_internet_address*/
90
91
92
93 /* * * * * * *
94  * this code badly needs to be cleaned up...  too many ugly ifdefs.
95  * XXX
96  */
97 extern afs_int32 afs_showflags;
98
99 afs_warn(a,b,c,d,e,f,g,h,i,j)
100 char *a;
101 long b,c,d,e,f,g,h,i,j;
102 {
103     AFS_STATCNT(afs_warn);
104     
105     if (afs_showflags & GAGCONSOLE)
106     {
107 #if defined(AFS_AIX_ENV)
108         struct file *fd;
109
110         /* cf. console_printf() in oncplus/kernext/nfs/serv/shared.c */
111         if (fp_open("/dev/console",O_WRONLY|O_NOCTTY|O_NDELAY,
112                     0666,0,FP_SYS,&fd) == 0) {
113             char buf[1024];
114             ssize_t len;
115             ssize_t count;
116
117             sprintf(buf, a,b,c,d,e,f,g,h,i,j);
118             len = strlen(buf);
119             fp_write(fd, buf, len, 0, UIO_SYSSPACE, &count);
120             fp_close(fd);
121         }
122 #else
123         printf(a,b,c,d,e,f,g,h,i,j);
124 #endif
125     }
126 }
127
128 afs_warnuser(a,b,c,d,e,f,g,h,i,j)
129 char *a;
130 long b,c,d,e,f,g,h,i,j;
131 {
132     AFS_STATCNT(afs_warnuser);
133     if (afs_showflags & GAGUSER)
134     {
135 #ifdef AFS_GLOBAL_SUNLOCK
136         int haveGlock = ISAFS_GLOCK();
137         if (haveGlock)
138             AFS_GUNLOCK();
139 #endif /* AFS_GLOBAL_SUNLOCK */
140
141         uprintf(a,b,c,d,e,f,g,h,i,j);
142
143 #ifdef AFS_GLOBAL_SUNLOCK
144         if (haveGlock)
145             AFS_GLOCK();
146 #endif /* AFS_GLOBAL_SUNLOCK */
147     }
148 }
149
150
151 /* run everywhere, checking locks */
152 void afs_CheckLocks()
153
154 {
155     extern afs_rwlock_t afs_xconn, afs_xvolume, afs_xuser, afs_xcell;
156     extern afs_rwlock_t afs_xserver;
157     extern struct server *afs_servers[NSERVERS];
158     extern struct unixuser *afs_users[NUSERS];
159     extern unsigned char *afs_indexFlags;
160     register int i;
161
162     afs_warn("Looking for locked data structures.\n");
163     afs_warn("conn %x, volume %x, user %x, cell %x, server %x\n",
164             afs_xconn, afs_xvolume, afs_xuser, afs_xcell, afs_xserver);
165     {
166         register struct vcache *tvc;
167         AFS_STATCNT(afs_CheckLocks);
168
169         for(i=0;i<VCSIZE;i++) {
170             for(tvc = afs_vhashT[i]; tvc; tvc=tvc->hnext) {
171 #ifdef  AFS_OSF_ENV
172                 if (tvc->vrefCount > 1)
173 #else   /* AFS_OSF_ENV */
174                 if (tvc->vrefCount)
175 #endif
176                     afs_warn("Stat cache entry at %x is held\n", tvc);
177                 if (CheckLock(&tvc->lock))
178                     afs_warn("Stat entry at %x is locked\n", tvc);
179             }
180         }
181     }
182     {
183         register struct dcache *tdc;
184         for (i=0;i<afs_cacheFiles;i++) {
185             tdc = afs_indexTable[i];
186             if (tdc) {
187                 if (tdc->refCount)
188                     afs_warn("Disk entry %d at %x is held\n", i, tdc);
189             }
190             if (afs_indexFlags[i] & IFDataMod)
191                 afs_warn("Disk entry %d at %x has IFDataMod flag set.\n", i, tdc);
192         }
193     }
194     {
195        struct srvAddr *sa;
196        struct server *ts;
197        struct conn *tc;
198         for (i=0;i<NSERVERS;i++) {
199             for (ts = afs_servers[i]; ts; ts=ts->next) {
200                 if (ts->flags & SRVR_ISDOWN)
201                     printf("Server entry %x is marked down\n", ts);
202                 for (sa = ts->addr; sa; sa = sa->next_sa) {     
203                     for (tc = sa->conns; tc; tc=tc->next) {
204                        if (tc->refCount)
205                           afs_warn("conn at %x (server %x) is held\n", tc, sa->sa_ip);
206                     }
207                 }
208             }
209         }
210     }
211     {
212        struct volume *tv;
213         for (i=0;i<NVOLS;i++) {
214             for (tv = afs_volumes[i]; tv; tv=tv->next) {
215                 if (CheckLock(&tv->lock))
216                     afs_warn("volume at %x is locked\n", tv);
217                 if (tv->refCount)
218                     afs_warn("volume at %x is held\n", tv);
219             }
220         }
221     }
222     {
223        struct unixuser *tu;
224
225         for (i=0;i<NUSERS;i++) {
226             for (tu = afs_users[i]; tu; tu=tu->next) {
227                 if (tu->refCount) printf("user at %x is held\n", tu);
228             }
229         }
230     }
231     afs_warn("Done.\n");
232 }
233
234
235 int afs_noop() {
236     AFS_STATCNT(afs_noop);
237 #ifdef  AFS_OSF30_ENV
238     return (EOPNOTSUPP);
239 #else
240     return EINVAL;
241 #endif
242 }
243
244 int afs_badop() {
245     AFS_STATCNT(afs_badop);
246     osi_Panic("afs bad vnode op");
247     return 0;                   /* make SGI C compiler happy */
248 }
249
250 /*
251  * afs_data_pointer_to_int32() - returns least significant afs_int32 of the
252  * given data pointer, without triggering "cast truncates pointer"
253  * warnings.  We use this where we explicitly don't care whether a
254  * pointer is truncated -- it loses information where a pointer is
255  * larger than an afs_int32.
256  */
257
258 afs_int32
259 afs_data_pointer_to_int32(const void *p)
260 {
261         union {
262                 afs_int32  i32[sizeof(void *)/sizeof(afs_int32)];
263                 const void *p;
264         } ip;
265
266         int i32_sub;    /* subscript of least significant afs_int32 in ip.i32[] */
267
268         /* set i32_sub */
269
270         {
271                 /* used to determine the byte order of the system */
272
273                 union {
274                         char c[sizeof(int)/sizeof(char)];
275                         int  i;
276                 } ci;
277
278                 ci.i = 1;
279                 if (ci.c[0] == 1) {
280                         /* little-endian system */
281                         i32_sub = 0;
282                 } else {
283                         /* big-endian system */
284                         i32_sub = (sizeof ip.i32 / sizeof ip.i32[0]) - 1;
285                 }
286         }
287
288         ip.p = p;
289         return ip.i32[i32_sub];
290 }