* $Id: nfs_start.c,v 5.2.1.2 90/12/21 16:41:40 jsp Alpha $
* Copyright (c) 1990 Jan-Simon Pendry
* Copyright (c) 1990 Imperial College of Science, Technology & Medicine
* Copyright (c) 1990 The Regents of the University of California.
* This code is derived from software contributed to Berkeley by
* Jan-Simon Pendry at Imperial College, London.
* %sccs.include.redist.c%
* @(#)nfs_start.c 5.2 (Berkeley) %G%
extern jmp_buf select_intr
;
extern int select_intr_valid
;
* Use replacement for RPC/UDP transport
* so that we do NFS gatewaying.
#define svcudp_create svcudp2_create
extern SVCXPRT
*svcudp2_create
P((int));
extern void nfs_program_2();
extern void amq_program_1();
#define MASKED_SIGS (sigmask(SIGINT)|sigmask(SIGTERM)|sigmask(SIGCHLD)|sigmask(SIGHUP))
* Check that we are not burning resources
static void checkup(P_void
)
static char *max_mem
= 0;
extern caddr_t sbrk
P((int));
caddr_t next_mem
= sbrk(0);
} else*/ if (max_fd
< next_fd
) {
dlog("%d new fds allocated; total is %d",
next_fd
- max_fd
, next_fd
);
} else*/ if (max_mem
< next_mem
) {
dlog("%#x bytes of memory allocated; total is %#x (%d pages)",
((int)next_mem
+getpagesize()-1)/getpagesize());
static int do_select(smask
, fds
, fdp
, tvp
)
if (sig
= setjmp(select_intr
)) {
* Invalidate the current clock value
* Allow interrupts. If a signal
* occurs, then it will cause a longjmp
(void) sigsetmask(smask
);
nsel
= select(fds
, fdp
, (int *) 0, (int *) 0,
tvp
->tv_sec
? tvp
: (struct timeval
*) 0);
(void) sigblock(MASKED_SIGS
);
* Perhaps reload the cache?
if (do_mapc_reload
< clocktime()) {
do_mapc_reload
= clocktime() + ONE_HOUR
;
* Determine whether anything is left in
static int rpc_pending_now()
FD_SET(fwd_sock
, &readfds
);
int readfds
= (1 << fwd_sock
);
tvv
.tv_sec
= tvv
.tv_usec
= 0;
nsel
= select(max_fds
+1, &readfds
, (int *) 0, (int *) 0, &tvv
);
if (FD_ISSET(fwd_sock
, &readfds
))
if (readfds
& (1 << fwd_sock
))
static serv_state
run_rpc(P_void
)
int smask
= sigblock(MASKED_SIGS
);
next_softclock
= clocktime();
* Keep on trucking while we are in Run mode. This state
* is switched to Quit after all the file systems have
while ((int)amd_state
<= (int)Finishing
) {
FD_SET(fwd_sock
, &readfds
);
readfds
.fds_bits
[0] = svc_fds
;
FD_SET(fwd_sock
, &readfds
);
int readfds
= svc_fds
| (1 << fwd_sock
);
* If the full timeout code is not called,
* then recompute the time delta manually.
if (next_softclock
<= now
) {
if (amd_state
== Finishing
)
tvv
.tv_sec
= softclock();
tvv
.tv_sec
= next_softclock
- now
;
if (amd_state
== Finishing
&& last_used_map
< 0) {
dlog("Select waits for %ds", tvv
.tv_sec
);
dlog("Select waits for Godot");
nsel
= do_select(smask
, dtbsz
, &readfds
, &tvv
);
dlog("select interrupted");
/*dlog("select returned 0");*/
/* Read all pending NFS responses at once to avoid
having responses queue up as a consequence of
if (FD_ISSET(fwd_sock
, &readfds
)) {
FD_CLR(fwd_sock
, &readfds
);
if (readfds
& (1 << fwd_sock
)) {
readfds
&= ~(1 << fwd_sock
);
} while (rpc_pending_now() > 0);
* Anything left must be a normal
svc_getreq(readfds
.fds_bits
[0]);
(void) sigsetmask(smask
);
static int bindnfs_port(so
)
int error
= bind_resv_port(so
, &port
);
void unregister_amq(P_void
)
(void) pmap_unset(AMQ_PROGRAM
, AMQ_VERSION
);
int mount_automounter(ppid
)
int so
= socket(AF_INET
, SOCK_DGRAM
, 0);
if (so
< 0 || bindnfs_port(so
) < 0) {
perror("Can't create privileged nfs port");
if ((nfsxprt
= svcudp_create(so
)) == NULL
||
(amqp
= svcudp_create(so
)) == NULL
) {
plog(XLOG_FATAL
, "cannot create rpc/udp service");
if (!svc_register(nfsxprt
, NFS_PROGRAM
, NFS_VERSION
, nfs_program_2
, 0)) {
plog(XLOG_FATAL
, "unable to register (NFS_PROGRAM, NFS_VERSION, 0)");
* One or other of so, fwd_sock
* must be the highest fd on
* Construct the root automount node
* Pick up the pieces from a previous run
* This is likely to (indirectly) need the rpc_fwd package
* so it *must* come after the call to fwd_init().
if (restart_existing_mounts
)
* Mount the top-level auto-mountpoints
nmount
= mount_exported();
* Now safe to tell parent that we are up and running
plog(XLOG_FATAL
, "No work to do - quitting");
if (!svc_register(amqp
, AMQ_PROGRAM
, AMQ_VERSION
, amq_program_1
, IPPROTO_UDP
)) {
plog(XLOG_FATAL
, "unable to register (AMQ_PROGRAM, AMQ_VERSION, udp)");
* Start timeout_mp rolling
plog(XLOG_FATAL
, "run_rpc failed");