2 * Copyright 2000, International Business Machines Corporation and others.
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
10 #include <afsconfig.h>
11 #include "afs/param.h"
14 #include "afs/sysincludes.h" /* Standard vendor system headers */
15 #include "afsincludes.h" /* Afs-based standard headers */
16 #include "afs/afs_stats.h"
17 #include "rx/rx_globals.h"
18 #include "rx/rxstat.h"
19 #if !defined(UKERNEL) && !defined(AFS_LINUX20_ENV)
22 #include "h/hashing.h"
24 #if !defined(AFS_HPUX110_ENV) && !defined(AFS_DARWIN60_ENV)
25 #include "netinet/in_var.h"
27 #endif /* !defined(UKERNEL) */
28 #ifdef AFS_LINUX22_ENV
29 #include "h/smp_lock.h"
35 afs_int32 afs_termState = 0;
36 afs_int32 afs_gcpags = AFS_GCPAGS;
37 int afs_shuttingdown = 0;
38 int afs_cold_shutdown = 0;
39 int afs_resourceinit_flag = 0;
40 afs_int32 afs_nfs_server_addr;
41 struct interfaceAddr afs_cb_interface;
42 struct afs_osi_WaitHandle AFS_WaitHandler;
43 static struct rx_securityClass *srv_secobj;
44 static struct rx_securityClass *clt_secobj;
45 static struct rx_service *stats_svc;
46 static struct rx_service *pagcb_svc;
47 static struct rx_connection *rmtsys_conn;
48 char *afs_sysname = 0;
49 char *afs_sysnamelist[MAXNUMSYSNAMES];
50 int afs_sysnamecount = 0;
51 int afs_sysnamegen = 0;
52 afs_int32 afs_showflags = GAGUSER | GAGCONSOLE; /* show all messages */
57 afs_int32 now, last10MinCheck, last60MinCheck;
65 if (last10MinCheck + 600 < now) {
69 if (last60MinCheck + 3600 < now) {
74 now = 20000 - (osi_Time() - now);
75 afs_osi_Wait(now, &AFS_WaitHandler, 0);
77 if (afs_termState == AFSOP_STOP_AFS) {
78 #if defined(AFS_SUN5_ENV) || defined(RXK_LISTENER_ENV)
79 afs_termState = AFSOP_STOP_RXEVENT;
81 afs_termState = AFSOP_STOP_COMPLETE;
83 afs_osi_Wakeup(&afs_termState);
90 void afspag_Init(afs_int32 nfs_server_addr)
92 struct clientcred ccred;
93 struct rmtbulk idata, odata;
94 afs_int32 code, err, addr, obuf;
97 afs_uuid_create(&afs_cb_interface.uuid);
102 rx_Init(htons(7001));
104 AFS_STATCNT(afs_ResourceInit);
105 AFS_RWLOCK_INIT(&afs_xuser, "afs_xuser");
106 AFS_RWLOCK_INIT(&afs_xpagcell, "afs_xpagcell");
107 AFS_RWLOCK_INIT(&afs_xpagsys, "afs_xpagsys");
108 AFS_RWLOCK_INIT(&afs_icl_lock, "afs_icl_lock");
110 LOCK_INIT(&osi_fsplock, "osi_fsplock");
111 LOCK_INIT(&osi_flplock, "osi_flplock");
114 afs_resourceinit_flag = 1;
115 afs_nfs_server_addr = nfs_server_addr;
116 for (i = 0; i < MAXNUMSYSNAMES; i++)
117 afs_sysnamelist[i] = afs_osi_Alloc(MAXSYSNAME);
118 afs_sysname = afs_sysnamelist[0];
119 strcpy(afs_sysname, SYS_NAME);
120 afs_sysnamecount = 1;
123 srv_secobj = rxnull_NewServerSecurityObject();
124 stats_svc = rx_NewService(0, RX_STATS_SERVICE_ID, "rpcstats", &srv_secobj,
125 1, RXSTATS_ExecuteRequest);
126 pagcb_svc = rx_NewService(0, PAGCB_SERVICEID, "pagcb", &srv_secobj,
127 1, PAGCB_ExecuteRequest);
130 clt_secobj = rxnull_NewClientSecurityObject();
131 rmtsys_conn = rx_NewConnection(nfs_server_addr, htons(7009),
132 RMTSYS_SERVICEID, clt_secobj, 0);
134 #ifdef RXK_LISTENER_ENV
135 afs_start_thread(rxk_Listener, "Rx Listener");
137 afs_start_thread((void *)(void *)rx_ServerProc, "Rx Server Thread");
138 afs_start_thread(afs_rxevent_daemon, "Rx Event Daemon");
139 afs_start_thread(afs_Daemon, "AFS PAG Daemon");
145 /* If it's reachable, tell the translator to nuke our creds.
146 * We should be more agressive about making sure this gets done,
147 * even if the translator is unreachable when we boot.
149 addr = obuf = err = 0;
150 idata.rmtbulk_len = sizeof(addr);
151 idata.rmtbulk_val = (char *)&addr;
152 odata.rmtbulk_len = sizeof(obuf);
153 odata.rmtbulk_val = (char *)&obuf;
154 memset(&ccred, 0, sizeof(ccred));
155 code = RMTSYS_Pioctl(rmtsys_conn, &ccred, NIL_PATHP, 0x4F01, 0,
156 &idata, &odata, &err);
157 } /*afs_ResourceInit */
160 /* called with the GLOCK held */
161 void afspag_Shutdown(void)
163 if (afs_shuttingdown)
165 afs_shuttingdown = 1;
166 afs_termState = AFSOP_STOP_RXCALLBACK;
167 rx_WakeupServerProcs();
168 while (afs_termState == AFSOP_STOP_RXCALLBACK)
169 afs_osi_Sleep(&afs_termState);
170 /* rx_ServerProc sets AFS_STOP_AFS */
172 while (afs_termState == AFSOP_STOP_AFS) {
173 afs_osi_CancelWait(&AFS_WaitHandler);
174 afs_osi_Sleep(&afs_termState);
176 /* afs_Daemon sets AFS_STOP_RXEVENT */
178 #if defined(AFS_SUN5_ENV) || defined(RXK_LISTENER_ENV)
179 while (afs_termState == AFSOP_STOP_RXEVENT)
180 afs_osi_Sleep(&afs_termState);
181 /* afs_rxevent_daemon sets AFSOP_STOP_RXK_LISTENER */
183 #if defined(RXK_LISTENER_ENV)
184 afs_osi_UnmaskRxkSignals();
186 while (afs_termState == AFSOP_STOP_RXK_LISTENER)
187 afs_osi_Sleep(&afs_termState);
188 /* rxk_Listener sets AFSOP_STOP_COMPLETE */
193 static void token_conversion(char *buffer, int buf_size, int in)
195 struct ClearToken *ticket;
199 if (buf_size < 4) return;
200 lptr = (afs_int32 *)buffer;
201 buffer += 4; buf_size -= 4;
203 *lptr = ntohl(*lptr);
207 *lptr = htonl(*lptr);
209 if (n < 0 || buf_size < n) return;
210 buffer += n; buf_size -= n;
213 if (buf_size < 4) return;
214 lptr = (afs_int32 *)buffer;
215 buffer += 4; buf_size -= 4;
217 *lptr = ntohl(*lptr);
221 *lptr = htonl(*lptr);
223 if (n < 0 || buf_size < n) return;
224 if (n >= sizeof(struct ClearToken)) {
225 ticket = (struct ClearToken *)buffer;
227 ticket->AuthHandle = ntohl(ticket->AuthHandle);
228 ticket->ViceId = ntohl(ticket->ViceId);
229 ticket->BeginTimestamp = ntohl(ticket->BeginTimestamp);
230 ticket->EndTimestamp = ntohl(ticket->EndTimestamp);
232 ticket->AuthHandle = htonl(ticket->AuthHandle);
233 ticket->ViceId = htonl(ticket->ViceId);
234 ticket->BeginTimestamp = htonl(ticket->BeginTimestamp);
235 ticket->EndTimestamp = htonl(ticket->EndTimestamp);
238 buffer += n; buf_size -= n;
241 if (buf_size < 4) return;
242 lptr = (afs_int32 *)buffer;
244 *lptr = ntohl(*lptr);
246 *lptr = htonl((*lptr) & ~0x8000);
251 static void FetchVolumeStatus_conversion(char *buffer, int buf_size, int in)
253 AFSFetchVolumeStatus *status = (AFSFetchVolumeStatus *)buffer;
255 if (buf_size < sizeof(AFSFetchVolumeStatus))
258 status->Vid = ntohl(status->Vid);
259 status->ParentId = ntohl(status->ParentId);
260 status->Type = ntohl(status->Type);
261 status->MinQuota = ntohl(status->MinQuota);
262 status->MaxQuota = ntohl(status->MaxQuota);
263 status->BlocksInUse = ntohl(status->BlocksInUse);
264 status->PartBlocksAvail = ntohl(status->PartBlocksAvail);
265 status->PartMaxBlocks = ntohl(status->PartMaxBlocks);
267 status->Vid = htonl(status->Vid);
268 status->ParentId = htonl(status->ParentId);
269 status->Type = htonl(status->Type);
270 status->MinQuota = htonl(status->MinQuota);
271 status->MaxQuota = htonl(status->MaxQuota);
272 status->BlocksInUse = htonl(status->BlocksInUse);
273 status->PartBlocksAvail = htonl(status->PartBlocksAvail);
274 status->PartMaxBlocks = htonl(status->PartMaxBlocks);
278 static void inparam_conversion(int cmd, char *buffer, int buf_size, int in)
280 afs_int32 *lptr = (afs_int32 *)buffer;
282 switch (cmd & 0xffff) {
283 case (0x5600 | 3): /* VIOCSETTOK */
284 token_conversion(buffer, buf_size, in);
287 case (0x5600 | 5): /* VIOCSETVOLSTAT */
288 FetchVolumeStatus_conversion(buffer, buf_size, in);
291 case (0x5600 | 8): /* VIOCGETTOK */
292 case (0x5600 | 10): /* VIOCCKSERV */
293 case (0x5600 | 20): /* VIOCACCESS */
294 case (0x5600 | 24): /* VIOCSETCACHESIZE */
295 case (0x5600 | 27): /* VIOCGETCELL */
296 case (0x5600 | 32): /* VIOC_AFS_MARINER_HOST */
297 case (0x5600 | 34): /* VIOC_VENUSLOG */
298 case (0x5600 | 38): /* VIOC_AFS_SYSNAME */
299 case (0x5600 | 39): /* VIOC_EXPORTAFS */
300 /* one 32-bit integer */
302 if (in) lptr[0] = ntohl(lptr[0]);
303 else lptr[0] = htonl(lptr[0]);
307 case (0x5600 | 36): /* VIOCSETCELLSTATUS */
308 /* two 32-bit integers */
310 if (in) lptr[0] = ntohl(lptr[0]);
311 else lptr[0] = htonl(lptr[0]);
314 if (in) lptr[1] = ntohl(lptr[1]);
315 else lptr[1] = htonl(lptr[1]);
321 static void outparam_conversion(int cmd, char *buffer, int buf_size, int in)
323 afs_int32 *lptr = (afs_int32 *)buffer;
326 switch (cmd & 0xffff) {
327 case (0x5600 | 4): /* VIOCGETVOLSTAT */
328 case (0x5600 | 5): /* VIOCSETVOLSTAT */
329 FetchVolumeStatus_conversion(buffer, buf_size, in);
332 case (0x5600 | 8): /* VIOCGETTOK */
333 token_conversion(buffer, buf_size, in);
336 case (0x5600 | 12): /* VIOCCKCONN */
337 case (0x5600 | 32): /* VIOC_AFS_MARINER_HOST */
338 case (0x5600 | 34): /* VIOC_VENUSLOG */
339 case (0x5600 | 35): /* VIOC_GETCELLSTATUS */
340 case (0x5600 | 38): /* VIOC_AFS_SYSNAME */
341 case (0x5600 | 39): /* VIOC_EXPORTAFS */
342 /* one 32-bit integer */
344 if (in) lptr[0] = ntohl(lptr[0]);
345 else lptr[0] = htonl(lptr[0]);
349 case (0x5600 | 40): /* VIOCGETCACHEPARMS */
350 /* sixteen 32-bit integers */
351 for (i = 0; i < 16 && buf_size >= 4; i++) {
352 if (in) lptr[i] = ntohl(lptr[i]);
353 else lptr[i] = htonl(lptr[i]);
361 /* called with the GLOCK held */
364 afs_syscall_pioctl(path, com, cmarg, follow, rvp, credp)
368 #if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
369 afs_syscall_pioctl(path, com, cmarg, follow, credp)
372 afs_syscall_pioctl(path, com, cmarg, follow)
381 struct ucred *credp = crref(); /* don't free until done! */
383 #ifdef AFS_LINUX22_ENV
384 cred_t *credp = crref(); /* don't free until done! */
386 struct afs_ioctl data;
387 struct clientcred ccred;
388 struct rmtbulk idata, odata;
389 short in_size, out_size;
390 afs_int32 code = 0, pag, err;
392 char *abspath, *pathbuf = 0;
394 AFS_STATCNT(afs_syscall_pioctl);
396 follow = 1; /* compat. with old venus */
397 code = copyin_afs_ioctl(cmarg, &data);
400 if ((com & 0xff) == 90) {
401 /* PSetClientContext, in any space */
406 /* Special handling for a few pioctls */
407 switch (com & 0xffff) {
408 case (0x5600 | 3): /* VIOCSETTOK */
409 code = afspag_PSetTokens(data.in, data.in_size, &credp);
413 case (0x5600 | 9): /* VIOCUNLOG */
414 case (0x5600 | 21): /* VIOCUNPAG */
415 code = afspag_PUnlog(data.in, data.in_size, &credp);
419 case (0x5600 | 38): /* VIOC_AFS_SYSNAME */
420 code = afspag_PSetSysName(data.in, data.in_size, &credp);
425 /* Set up credentials */
426 memset(&ccred, 0, sizeof(ccred));
427 pag = PagInCred(credp);
428 ccred.uid = credp->cr_uid;
430 afs_get_groups_from_pag(pag, &g0, &g1);
436 * Copy the path and convert to absolute, if one was given.
437 * NB: We can only use osI_AllocLargeSpace here as long as
438 * RMTSYS_MAXPATHLEN is less than AFS_LRALLOCSIZ.
441 pathbuf = osi_AllocLargeSpace(RMTSYS_MAXPATHLEN);
446 code = osi_abspath(path, pathbuf, RMTSYS_MAXPATHLEN, 0, &abspath);
453 /* Allocate, copy, and convert incoming data */
454 idata.rmtbulk_len = in_size = data.in_size;
455 if (in_size < 0 || in_size > MAXBUFFERLEN) {
459 if (in_size > AFS_LRALLOCSIZ)
460 idata.rmtbulk_val = osi_Alloc(in_size);
462 idata.rmtbulk_val = osi_AllocLargeSpace(AFS_LRALLOCSIZ);
463 if (!idata.rmtbulk_val) {
468 AFS_COPYIN(data.in, idata.rmtbulk_val, in_size, code);
471 inparam_conversion(com, idata.rmtbulk_val, in_size, 0);
474 /* Allocate space for outgoing data */
475 odata.rmtbulk_len = out_size = data.out_size;
476 if (out_size < 0 || out_size > MAXBUFFERLEN) {
480 if (out_size > AFS_LRALLOCSIZ)
481 odata.rmtbulk_val = osi_Alloc(out_size);
483 odata.rmtbulk_val = osi_AllocLargeSpace(AFS_LRALLOCSIZ);
484 if (!odata.rmtbulk_val) {
490 code = RMTSYS_Pioctl(rmtsys_conn, &ccred, abspath, com, follow,
491 &idata, &odata, &err);
496 /* Convert and copy out the result */
497 if (odata.rmtbulk_len > out_size) {
501 if (odata.rmtbulk_len) {
502 outparam_conversion(com, odata.rmtbulk_val, odata.rmtbulk_len, 1);
503 AFS_COPYOUT(odata.rmtbulk_val, data.out, odata.rmtbulk_len, code);
509 if (out_size > AFS_LRALLOCSIZ)
510 osi_Free(odata.rmtbulk_val, out_size);
512 osi_FreeLargeSpace(odata.rmtbulk_val);
515 if (in_size > AFS_LRALLOCSIZ)
516 osi_Free(idata.rmtbulk_val, in_size);
518 osi_FreeLargeSpace(idata.rmtbulk_val);
522 osi_FreeLargeSpace(pathbuf);
525 #if defined(AFS_LINUX22_ENV) || defined(AFS_AIX41_ENV)
528 #if defined(KERNEL_HAVE_UERROR)
531 return (getuerror());
539 afs_syscall_call(parm, parm2, parm3, parm4, parm5, parm6)
540 long parm, parm2, parm3, parm4, parm5, parm6;
542 /* superusers may shut us down, as with afsd --shutdown */
544 if (parm == AFSOP_SHUTDOWN && afs_suser(CRED()))
546 if (parm == AFSOP_SHUTDOWN && afs_suser(NULL))
555 /* otherwise, we don't support afs_syscall_call, period */
556 #if defined(KERNEL_HAVE_UERROR)